eo301@0
|
1 #include "MP4Movies.h"
|
eo301@0
|
2 #include "MP4LinkedList.h"
|
eo301@0
|
3 #include "MP4InputStream.h"
|
eo301@0
|
4 #include "IM_AF_Decoder.h"
|
eo301@0
|
5
|
eo301@0
|
6 #ifndef BAILWITHERROR
|
eo301@0
|
7 #define BAILWITHERROR(v) \
|
eo301@0
|
8 { \
|
eo301@0
|
9 err = (v); \
|
eo301@0
|
10 goto bail; \
|
eo301@0
|
11 }
|
eo301@0
|
12 #endif
|
eo301@0
|
13
|
eo301@0
|
14 typedef struct IMAFDecoder
|
eo301@0
|
15 {
|
eo301@0
|
16 u8 *InputMafFilename;
|
eo301@0
|
17 FILE *InputFp;
|
eo301@0
|
18 u32 TrackCount;
|
eo301@0
|
19 // u32 CompletedTrackCount;
|
eo301@0
|
20 u32 HasTimedTextTrack;
|
eo301@0
|
21
|
eo301@0
|
22 MP4Movie moov;
|
eo301@0
|
23 MP4Track trak;
|
eo301@0
|
24 MP4Media media;
|
eo301@0
|
25 u32 MovieTimescale;
|
eo301@0
|
26 u32 MovieDuration;
|
eo301@0
|
27
|
eo301@0
|
28 // Multi audio track
|
eo301@0
|
29 MP4LinkedList TrackReaderList; // for all Track
|
eo301@0
|
30 MP4LinkedList TrackSampleList; // for all Track Sample
|
eo301@0
|
31
|
eo301@0
|
32 MP4TrackReader TimedTextTrackReader;
|
eo301@0
|
33 MP4Handle TimedTextSampleH;
|
eo301@0
|
34 MP4Handle TextH;
|
eo301@0
|
35 u32 TimedTextTrackIndex;
|
eo301@0
|
36 TextSampleStyleParam *TextParam;
|
eo301@0
|
37
|
eo301@0
|
38 unsigned int HasSaocTrack;
|
eo301@0
|
39 }IMAFDecoder;
|
eo301@0
|
40
|
eo301@0
|
41 void InitTextSampleStyleParam(TextSampleStyleParam *TextParam)
|
eo301@0
|
42 {
|
eo301@0
|
43 if(TextParam)
|
eo301@0
|
44 {
|
eo301@0
|
45 if(TextParam->styl_text_styles)
|
eo301@0
|
46 free(TextParam->styl_text_styles);
|
eo301@0
|
47 if(TextParam->krok_highlight_end_time)
|
eo301@0
|
48 free(TextParam->krok_highlight_end_time);
|
eo301@0
|
49 if(TextParam->krok_startcharoffset)
|
eo301@0
|
50 free(TextParam->krok_startcharoffset);
|
eo301@0
|
51 if(TextParam->krok_endcharoffset)
|
eo301@0
|
52 free(TextParam->krok_endcharoffset);
|
eo301@0
|
53 if(TextParam->font)
|
eo301@0
|
54 free(TextParam->font);
|
eo301@0
|
55 memset(TextParam, 0, sizeof(TextSampleStyleParam));
|
eo301@0
|
56 }
|
eo301@0
|
57 }
|
eo301@0
|
58
|
eo301@0
|
59 IMAF_DECODER_API IMAF_Err IMAF_Decoder_Create(IMAF_DecoderH *IMafDecoder, IMAF_Decoder_Param *param)
|
eo301@0
|
60 {
|
eo301@0
|
61 IMAFDecoder *decoder = NULL;
|
eo301@0
|
62 MP4Err err;
|
eo301@0
|
63 u32 i;
|
eo301@0
|
64 u32 sample_desc_type;
|
eo301@0
|
65 MP4TrackReader reader;
|
eo301@0
|
66 MP4Handle sampleH;
|
eo301@0
|
67 u32 minorVersion;
|
eo301@0
|
68
|
eo301@0
|
69 decoder = calloc(1, sizeof(IMAFDecoder));
|
eo301@0
|
70
|
eo301@0
|
71 if(param == NULL || param->InputMafFilename == NULL)
|
eo301@0
|
72 {
|
eo301@0
|
73 err = MP4BadParamErr;
|
eo301@0
|
74 goto bail;
|
eo301@0
|
75 }
|
eo301@0
|
76 else
|
eo301@0
|
77 decoder->InputMafFilename = _strdup(param->InputMafFilename);
|
eo301@0
|
78
|
eo301@0
|
79 err = MP4OpenMovieFile( &decoder->moov, decoder->InputMafFilename, MP4OpenMovieInPlace ); if (err) goto bail;
|
eo301@0
|
80 err = MP4GetMovieTrackCount( decoder->moov, &decoder->TrackCount); if(err) goto bail;
|
eo301@0
|
81
|
eo301@0
|
82 //Timed Text
|
eo301@0
|
83 for(i=0; i<decoder->TrackCount; i++)
|
eo301@0
|
84 {
|
eo301@0
|
85 err = MP4GetMovieIndTrack( decoder->moov, i+1, &decoder->trak ); if (err) goto bail;
|
eo301@0
|
86 err = MP4GetTrackMedia( decoder->trak, &decoder->media ); if (err) goto bail;
|
eo301@0
|
87 err = MP4GetMediaSampleDescriptionType(decoder->media, &sample_desc_type); if(err) goto bail;
|
eo301@0
|
88 if(sample_desc_type == 'tx3g')
|
eo301@0
|
89 {
|
eo301@0
|
90 decoder->HasTimedTextTrack = 1;
|
eo301@0
|
91 decoder->TimedTextTrackIndex = i;
|
eo301@0
|
92 break;
|
eo301@0
|
93 }
|
eo301@0
|
94 }
|
eo301@0
|
95
|
eo301@0
|
96 param->HasTimedTextTrack = decoder->HasTimedTextTrack;
|
eo301@0
|
97 param->NumberOfAudioTrack = decoder->TrackCount - decoder->HasTimedTextTrack;
|
eo301@0
|
98
|
eo301@0
|
99 err = MP4GetMovieTimeScale(decoder->moov, &decoder->MovieTimescale); if(err) goto bail;
|
eo301@0
|
100 param->MovieTimescale = decoder->MovieTimescale;
|
eo301@0
|
101
|
eo301@0
|
102 err = MP4GetMovieDuration(decoder->moov, (u64*)&decoder->MovieDuration); if(err) goto bail;
|
eo301@0
|
103 param->MovieDuration = decoder->MovieDuration;
|
eo301@0
|
104
|
eo301@0
|
105 // Create TrackReader for all Track
|
eo301@0
|
106 err = MP4MakeLinkedList( &decoder->TrackReaderList); if(err) goto bail;
|
eo301@0
|
107 err = MP4MakeLinkedList( &decoder->TrackSampleList); if(err) goto bail;
|
eo301@0
|
108 for(i=0; i<decoder->TrackCount; i++)
|
eo301@0
|
109 {
|
eo301@0
|
110 err = MP4GetMovieIndTrack( decoder->moov, i+1, &decoder->trak ); if (err) goto bail;
|
eo301@0
|
111 if(decoder->HasTimedTextTrack && decoder->TimedTextTrackIndex == i)
|
eo301@0
|
112 {
|
eo301@0
|
113 err = MP4CreateTrackReader( decoder->trak, &reader ); if (err) goto bail;
|
eo301@0
|
114 decoder->TimedTextTrackReader = reader;
|
eo301@0
|
115 }
|
eo301@0
|
116 else
|
eo301@0
|
117 {
|
eo301@0
|
118 err = MP4CreateTrackReader( decoder->trak, &reader ); if (err) goto bail;
|
eo301@0
|
119 err = MP4AddListEntry( reader, decoder->TrackReaderList); if (err) goto bail;
|
eo301@0
|
120
|
eo301@0
|
121 err = MP4NewHandle(0, &sampleH); if(err) goto bail;
|
eo301@0
|
122 err = MP4AddListEntry( sampleH, decoder->TrackSampleList); if (err) goto bail;
|
eo301@0
|
123 }
|
eo301@0
|
124 }
|
eo301@0
|
125
|
eo301@0
|
126 err = MP4NewHandle(0, &decoder->TimedTextSampleH); if(err) goto bail;
|
eo301@0
|
127 err = MP4NewHandle(0, &decoder->TextH); if(err) goto bail;
|
eo301@0
|
128
|
eo301@0
|
129 decoder->TextParam = calloc(1, sizeof(TextSampleStyleParam));
|
eo301@0
|
130
|
eo301@0
|
131 err = ISOGetMovieBrand(decoder->moov, ¶m->MajorBrand, &minorVersion); if(err) goto bail;
|
eo301@0
|
132 err = ISOGetNbCompatableBrands(decoder->moov, ¶m->NumberOfCompatibleBrands); if(err) goto bail;
|
eo301@0
|
133 if(param->NumberOfCompatibleBrands)
|
eo301@0
|
134 {
|
eo301@0
|
135 param->CompatibleBrands = calloc(param->NumberOfCompatibleBrands, sizeof(u32));
|
eo301@0
|
136 err = ISOGetCompatableBrands(decoder->moov, param->CompatibleBrands); if(err) goto bail;
|
eo301@0
|
137 }
|
eo301@0
|
138 else
|
eo301@0
|
139 param->CompatibleBrands = NULL;
|
eo301@0
|
140
|
eo301@0
|
141
|
eo301@0
|
142 *IMafDecoder = decoder;
|
eo301@0
|
143
|
eo301@0
|
144 bail:
|
eo301@0
|
145 TEST_RETURN( err );
|
eo301@0
|
146 return err;
|
eo301@0
|
147 }
|
eo301@0
|
148
|
eo301@0
|
149 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetAudioTrackInfos(IMAF_DecoderH IMafDecoder, unsigned int *AudioTrackObjectTypeArray
|
eo301@0
|
150 ,unsigned int *AudioTrackIdArray, IMAF_AudioParam *AudioParamArray)
|
eo301@0
|
151 {
|
eo301@0
|
152 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
153 IMAF_Err err;
|
eo301@0
|
154 u32 i;
|
eo301@0
|
155 u32 outObjectType, sample_desc_type;
|
eo301@0
|
156 u32 hasTimedText = 0;
|
eo301@0
|
157 u32 trackID;
|
eo301@0
|
158 unsigned int nBitsPerSample;
|
eo301@0
|
159 unsigned int nChannels;
|
eo301@0
|
160 unsigned int nSamplingFrequency;
|
eo301@0
|
161 for(i=0; i<decoder->TrackCount - decoder->HasTimedTextTrack; i++)
|
eo301@0
|
162 {
|
eo301@0
|
163 err = MP4GetMovieIndTrack( decoder->moov, i+1, &decoder->trak ); if (err) goto bail;
|
eo301@0
|
164 err = MP4GetTrackMedia( decoder->trak, &decoder->media ); if (err) goto bail;
|
eo301@0
|
165 err = MP4GetMediaSampleDescriptionType(decoder->media, &sample_desc_type); if(err) goto bail;
|
eo301@0
|
166 if(sample_desc_type == 'mp4a')
|
eo301@0
|
167 {
|
eo301@0
|
168 err = MP4GetTrackID(decoder->trak, &trackID); if(err) goto bail;
|
eo301@0
|
169 AudioTrackIdArray[i - hasTimedText] = trackID;
|
eo301@0
|
170 err = MP4GetMediaDecoderType( decoder->media, 1, &outObjectType, NULL, NULL, NULL ); if(err) goto bail;
|
eo301@0
|
171 if(outObjectType == AUDIO_OBJECT_TYPE_INDICATION_MP3 || outObjectType == AUDIO_OBJECT_TYPE_INDICATION_AAC
|
eo301@0
|
172 || outObjectType == AUDIO_OBJECT_TYPE_INDICATION_SAOC|| outObjectType == AUDIO_OBJECT_TYPE_INDICATION_PCM)
|
eo301@0
|
173 {
|
eo301@0
|
174 AudioTrackObjectTypeArray[i - hasTimedText] = outObjectType;
|
eo301@0
|
175 if(outObjectType = AUDIO_OBJECT_TYPE_INDICATION_SAOC)
|
eo301@0
|
176 decoder->HasSaocTrack = 1;
|
eo301@0
|
177 }
|
eo301@0
|
178 else
|
eo301@0
|
179 BAILWITHERROR(MP4BadDataErr)
|
eo301@0
|
180
|
eo301@0
|
181 err = MP4GetSampleRateChannelBitsPerSample(decoder->media, &nSamplingFrequency, &nChannels, &nBitsPerSample); if(err) goto bail;
|
eo301@0
|
182 AudioParamArray[i].nSamplingFrequency = nSamplingFrequency;
|
eo301@0
|
183 AudioParamArray[i].nChannels = nChannels;
|
eo301@0
|
184 AudioParamArray[i].nBitsPerSample = nBitsPerSample;
|
eo301@0
|
185 }
|
eo301@0
|
186 else
|
eo301@0
|
187 {
|
eo301@0
|
188 hasTimedText = 1;
|
eo301@0
|
189 }
|
eo301@0
|
190 }
|
eo301@0
|
191
|
eo301@0
|
192 bail:
|
eo301@0
|
193 TEST_RETURN( err );
|
eo301@0
|
194 return err;
|
eo301@0
|
195 }
|
eo301@0
|
196
|
eo301@0
|
197 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetGroupContainerInfo(IMAF_DecoderH IMafDecoder, unsigned int *GroupCount)
|
eo301@0
|
198 {
|
eo301@0
|
199 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
200 IMAF_Err err;
|
eo301@0
|
201
|
eo301@0
|
202 err = MP4GetGroupContainerInfo(decoder->moov, GroupCount); if(err) goto bail;
|
eo301@0
|
203
|
eo301@0
|
204 bail:
|
eo301@0
|
205 TEST_RETURN( err );
|
eo301@0
|
206 return err;
|
eo301@0
|
207 }
|
eo301@0
|
208
|
eo301@0
|
209 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetGroupByIndex(IMAF_DecoderH IMafDecoder, unsigned int i, IMAF_Group *grup)
|
eo301@0
|
210 {
|
eo301@0
|
211 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
212 IMAF_Err err;
|
eo301@0
|
213 unsigned int *element_ID;
|
eo301@0
|
214 char *group_name;
|
eo301@0
|
215 char *group_description;
|
eo301@0
|
216
|
eo301@0
|
217 err = MP4GetGroupByIndex(decoder->moov, i,
|
eo301@0
|
218 &grup->group_ID,
|
eo301@0
|
219 &grup->num_elements,
|
eo301@0
|
220 &element_ID,
|
eo301@0
|
221 &grup->group_activation_mode,
|
eo301@0
|
222 &grup->group_activation_elements_number,
|
eo301@0
|
223 &grup->group_reference_volume,
|
eo301@0
|
224 &group_name,
|
eo301@0
|
225 &group_description); if(err) goto bail;
|
eo301@0
|
226
|
eo301@0
|
227 grup->element_ID =(u32*) calloc( grup->num_elements, sizeof(u32) );
|
eo301@0
|
228 memcpy(grup->element_ID, element_ID, sizeof(u32)*grup->num_elements);
|
eo301@0
|
229 if(group_name)
|
eo301@0
|
230 grup->group_name = _strdup(group_name);
|
eo301@0
|
231 else
|
eo301@0
|
232 grup->group_name = NULL;
|
eo301@0
|
233 if(group_description)
|
eo301@0
|
234 grup->group_description = _strdup(group_description);
|
eo301@0
|
235 else
|
eo301@0
|
236 grup->group_description = NULL;
|
eo301@0
|
237
|
eo301@0
|
238 bail:
|
eo301@0
|
239 TEST_RETURN( err );
|
eo301@0
|
240 return err;
|
eo301@0
|
241 }
|
eo301@0
|
242
|
eo301@0
|
243 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetPresetContainerInfo(IMAF_DecoderH IMafDecoder, unsigned int *num_preset, unsigned int *default_preset_ID)
|
eo301@0
|
244 {
|
eo301@0
|
245 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
246 IMAF_Err err;
|
eo301@0
|
247
|
eo301@0
|
248 err = MP4GetPresetContainerInfo(decoder->moov, num_preset, default_preset_ID); if(err) goto bail;
|
eo301@0
|
249
|
eo301@0
|
250 bail:
|
eo301@0
|
251 TEST_RETURN( err );
|
eo301@0
|
252 return err;
|
eo301@0
|
253 }
|
eo301@0
|
254
|
eo301@0
|
255 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetPresetByIndex(IMAF_DecoderH IMafDecoder, unsigned int i, IMAF_Preset *prst)
|
eo301@0
|
256 {
|
eo301@0
|
257 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
258 IMAF_Err err;
|
eo301@0
|
259
|
eo301@0
|
260 u32 *preset_element_ID;
|
eo301@0
|
261 u32 *preset_volume_element;
|
eo301@0
|
262 u32 *num_input_channel;
|
eo301@0
|
263 u32 *updated_sample_number;
|
eo301@0
|
264 char *preset_name;
|
eo301@0
|
265 u32 ii;
|
eo301@0
|
266 u32 element_count;
|
eo301@0
|
267
|
eo301@0
|
268 err = MP4GetPresetByIndex(decoder->moov, i,
|
eo301@0
|
269 &prst->preset_ID,
|
eo301@0
|
270 &prst->num_preset_elements,
|
eo301@0
|
271 &preset_element_ID,
|
eo301@0
|
272 &prst->preset_type,
|
eo301@0
|
273 &prst->preset_global_volume,
|
eo301@0
|
274 &preset_volume_element,
|
eo301@0
|
275 &num_input_channel ,
|
eo301@0
|
276 &prst->output_channel_type ,
|
eo301@0
|
277 &prst->num_output_channel ,
|
eo301@0
|
278 &prst->num_updates ,
|
eo301@0
|
279 &updated_sample_number,
|
eo301@0
|
280 &preset_name); if(err) goto bail;
|
eo301@0
|
281
|
eo301@0
|
282 prst->preset_element_ID =(u32*) calloc( prst->num_preset_elements, sizeof(u32) );
|
eo301@0
|
283 memcpy(prst->preset_element_ID, preset_element_ID, sizeof(u32)*prst->num_preset_elements);
|
eo301@0
|
284 if(prst->preset_type == 0)
|
eo301@0
|
285 {
|
eo301@0
|
286 element_count = prst->num_preset_elements;
|
eo301@0
|
287 prst->preset_volume_element =(u32*) calloc( element_count, sizeof(u32) );
|
eo301@0
|
288 for(ii=0; ii<element_count; ii++)
|
eo301@0
|
289 prst->preset_volume_element[ii] = preset_volume_element[ii]*2;
|
eo301@0
|
290 }
|
eo301@0
|
291 else if(prst->preset_type == 1)
|
eo301@0
|
292 {
|
eo301@0
|
293 element_count = prst->num_preset_elements*num_input_channel[0]*prst->num_output_channel;
|
eo301@0
|
294 prst->preset_volume_element =(u32*) calloc( element_count, sizeof(u32) );
|
eo301@0
|
295 for(ii=0; ii<element_count; ii++)
|
eo301@0
|
296 prst->preset_volume_element[ii] = preset_volume_element[ii]*2;
|
eo301@0
|
297 }
|
eo301@0
|
298 else if(prst->preset_type == 2)
|
eo301@0
|
299 {
|
eo301@0
|
300 element_count = prst->num_preset_elements * prst->num_updates;
|
eo301@0
|
301 prst->preset_volume_element =(u32*) calloc( element_count, sizeof(u32) );
|
eo301@0
|
302 for(ii=0; ii<element_count; ii++)
|
eo301@0
|
303 prst->preset_volume_element[ii] = preset_volume_element[ii]*2;
|
eo301@0
|
304 }
|
eo301@0
|
305 else if(prst->preset_type == 3)
|
eo301@0
|
306 {
|
eo301@0
|
307 element_count = prst->num_updates*prst->num_preset_elements*num_input_channel[0]*prst->num_output_channel;
|
eo301@0
|
308 prst->preset_volume_element =(u32*) calloc( element_count, sizeof(u32) );
|
eo301@0
|
309 for(ii=0; ii<element_count; ii++)
|
eo301@0
|
310 prst->preset_volume_element[ii] = preset_volume_element[ii]*2;
|
eo301@0
|
311 }
|
eo301@0
|
312
|
eo301@0
|
313 if(num_input_channel)
|
eo301@0
|
314 {
|
eo301@0
|
315 prst->num_input_channel =(u32*) calloc( prst->num_preset_elements, sizeof(u32) );
|
eo301@0
|
316 memcpy(prst->num_input_channel, num_input_channel, sizeof(u32)*prst->num_preset_elements);
|
eo301@0
|
317 }
|
eo301@0
|
318 else
|
eo301@0
|
319 prst->num_input_channel = NULL;
|
eo301@0
|
320 if(updated_sample_number)
|
eo301@0
|
321 {
|
eo301@0
|
322 prst->updated_sample_number =(u32*) calloc( prst->num_updates, sizeof(u32) );
|
eo301@0
|
323 memcpy(prst->updated_sample_number, updated_sample_number, sizeof(u32)*prst->num_updates);
|
eo301@0
|
324 }
|
eo301@0
|
325 else
|
eo301@0
|
326 prst->updated_sample_number = NULL;
|
eo301@0
|
327 if(preset_name)
|
eo301@0
|
328 prst->preset_name = _strdup(preset_name);
|
eo301@0
|
329 else
|
eo301@0
|
330 prst->preset_name = NULL;
|
eo301@0
|
331
|
eo301@0
|
332 bail:
|
eo301@0
|
333 TEST_RETURN( err );
|
eo301@0
|
334 return err;
|
eo301@0
|
335 }
|
eo301@0
|
336
|
eo301@0
|
337 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetRuleContainerInfo(IMAF_DecoderH IMafDecoder, unsigned int *num_selection_rules, unsigned int *num_mixing_rules)
|
eo301@0
|
338 {
|
eo301@0
|
339 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
340 IMAF_Err err;
|
eo301@0
|
341
|
eo301@0
|
342 err = MP4GetRuleContainerInfo(decoder->moov, num_selection_rules, num_mixing_rules); if(err) goto bail;
|
eo301@0
|
343
|
eo301@0
|
344 bail:
|
eo301@0
|
345 TEST_RETURN( err );
|
eo301@0
|
346 return err;
|
eo301@0
|
347 }
|
eo301@0
|
348
|
eo301@0
|
349 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetSelectionRuleByIndex(IMAF_DecoderH IMafDecoder, unsigned int i, IMAF_SelectionRule *rusc)
|
eo301@0
|
350 {
|
eo301@0
|
351 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
352 IMAF_Err err;
|
eo301@0
|
353
|
eo301@0
|
354 char *selection_rule_description;
|
eo301@0
|
355 err = MP4GetSelectionRuleByIndex(decoder->moov, i,
|
eo301@0
|
356 &rusc->selection_rule_ID,
|
eo301@0
|
357 &rusc->selection_rule_type,
|
eo301@0
|
358 &rusc->element_ID,
|
eo301@0
|
359 &rusc->min_num_elements,
|
eo301@0
|
360 &rusc->max_num_elements,
|
eo301@0
|
361 &rusc->key_element_ID,
|
eo301@0
|
362 &selection_rule_description); if(err) goto bail;
|
eo301@0
|
363
|
eo301@0
|
364 if(selection_rule_description)
|
eo301@0
|
365 rusc->selection_rule_description = _strdup(selection_rule_description);
|
eo301@0
|
366 else
|
eo301@0
|
367 rusc->selection_rule_description = NULL;
|
eo301@0
|
368
|
eo301@0
|
369 bail:
|
eo301@0
|
370 TEST_RETURN( err );
|
eo301@0
|
371 return err;
|
eo301@0
|
372 }
|
eo301@0
|
373
|
eo301@0
|
374 IMAF_DECODER_API IMAF_Err IMAF_Decoder_GetMixingRuleByIndex(IMAF_DecoderH IMafDecoder, unsigned int i, IMAF_MixingRule *rumx)
|
eo301@0
|
375 {
|
eo301@0
|
376 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
377 IMAF_Err err;
|
eo301@0
|
378
|
eo301@0
|
379 char *mixing_rule_description;
|
eo301@0
|
380 err = MP4GetMixingRuleByIndex(decoder->moov, i,
|
eo301@0
|
381 &rumx->mixing_rule_ID,
|
eo301@0
|
382 &rumx->mixing_rule_type,
|
eo301@0
|
383 &rumx->element_ID,
|
eo301@0
|
384 &rumx->min_volume,
|
eo301@0
|
385 &rumx->max_volume,
|
eo301@0
|
386 &rumx->key_element_ID,
|
eo301@0
|
387 &mixing_rule_description); if(err) goto bail;
|
eo301@0
|
388
|
eo301@0
|
389 if(mixing_rule_description)
|
eo301@0
|
390 rumx->mixing_rule_description = _strdup(mixing_rule_description);
|
eo301@0
|
391 else
|
eo301@0
|
392 rumx->mixing_rule_description = NULL;
|
eo301@0
|
393
|
eo301@0
|
394 bail:
|
eo301@0
|
395 TEST_RETURN( err );
|
eo301@0
|
396 return err;
|
eo301@0
|
397 }
|
eo301@0
|
398
|
eo301@0
|
399 IMAF_DECODER_API IMAF_Err IMAFDecoder_SeekSample(IMAF_DecoderH IMafDecoder, unsigned int mediaTime)
|
eo301@0
|
400 {
|
eo301@0
|
401 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
402 IMAF_Err err;
|
eo301@0
|
403 u32 timescale, i;
|
eo301@0
|
404 MP4TrackReader reader;
|
eo301@0
|
405
|
eo301@0
|
406 err = MP4GetMediaTimeScale(decoder->media, ×cale); if(err) goto bail;
|
eo301@0
|
407 mediaTime /= 1000; //in miliseconds
|
eo301@0
|
408 mediaTime *= timescale;
|
eo301@0
|
409
|
eo301@0
|
410 for(i=0; i<decoder->TrackCount - decoder->HasTimedTextTrack; i++)
|
eo301@0
|
411 {
|
eo301@0
|
412 err = MP4GetListEntry(decoder->TrackReaderList, i, (char**)&reader); if(err) goto bail;
|
eo301@0
|
413 err = MP4TrackReaderSeekToSyncSample( reader, mediaTime); if(err) goto bail;
|
eo301@0
|
414 }
|
eo301@0
|
415 if(decoder->TimedTextTrackReader)
|
eo301@0
|
416 {
|
eo301@0
|
417 err = MP4TrackReaderSeekToSyncSample( decoder->TimedTextTrackReader, mediaTime); if(err) goto bail;
|
eo301@0
|
418 }
|
eo301@0
|
419
|
eo301@0
|
420 bail:
|
eo301@0
|
421 TEST_RETURN( err );
|
eo301@0
|
422 return err;
|
eo301@0
|
423 }
|
eo301@0
|
424
|
eo301@0
|
425 IMAF_DECODER_API IMAF_Err IMAFDecoder_GetNextAudioSampleByIndex(IMAF_DecoderH IMafDecoder, unsigned int i,
|
eo301@0
|
426 unsigned char **SampleData, unsigned int *SampleDataSize, unsigned int *CurrentTime, unsigned int *sampleNumber)
|
eo301@0
|
427 {
|
eo301@0
|
428 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
429 IMAF_Err err;
|
eo301@0
|
430 MP4TrackReader reader;
|
eo301@0
|
431 MP4Handle sampleH;
|
eo301@0
|
432 u32 unitSize;
|
eo301@0
|
433 u32 sampleFlags;
|
eo301@0
|
434 u32 cts;
|
eo301@0
|
435 u32 dts;
|
eo301@0
|
436
|
eo301@0
|
437 if(i >= decoder->TrackCount - decoder->HasTimedTextTrack)
|
eo301@0
|
438 BAILWITHERROR(MP4BadParamErr)
|
eo301@0
|
439 err = MP4GetListEntry(decoder->TrackReaderList, i, (char**)&reader); if(err) goto bail;
|
eo301@0
|
440 err = MP4GetListEntry(decoder->TrackSampleList, i, (char**)&sampleH); if(err) goto bail;
|
eo301@0
|
441 err = MP4TrackReaderGetNextAccessUnitWithSampleNumber( reader, sampleH, &unitSize,&sampleFlags, &cts, &dts, sampleNumber);
|
eo301@0
|
442
|
eo301@0
|
443 if ( err )
|
eo301@0
|
444 {
|
eo301@0
|
445 if ( err == MP4EOF )
|
eo301@0
|
446 {
|
eo301@0
|
447 *SampleData = NULL;
|
eo301@0
|
448 *SampleDataSize = 0;
|
eo301@0
|
449 *CurrentTime = 0;
|
eo301@0
|
450 err = MP4NoErr;
|
eo301@0
|
451 }
|
eo301@0
|
452 else
|
eo301@0
|
453 goto bail;
|
eo301@0
|
454 }
|
eo301@0
|
455
|
eo301@0
|
456 *CurrentTime = dts;
|
eo301@0
|
457 *SampleData = *sampleH;
|
eo301@0
|
458 *SampleDataSize = unitSize;
|
eo301@0
|
459 bail:
|
eo301@0
|
460 TEST_RETURN( err );
|
eo301@0
|
461 return err;
|
eo301@0
|
462 }
|
eo301@0
|
463
|
eo301@0
|
464 IMAF_DECODER_API IMAF_Err IMAFDecoder_GetNextTextSample(IMAF_DecoderH IMafDecoder,
|
eo301@0
|
465 unsigned char **SampleData, unsigned int *SampleDataSize, unsigned int *CurrentTime, TextSampleStyleParam **param)
|
eo301@0
|
466 {
|
eo301@0
|
467 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
468 IMAF_Err err;
|
eo301@0
|
469 u32 unitSize;
|
eo301@0
|
470 u32 sampleFlags;
|
eo301@0
|
471 u32 cts;
|
eo301@0
|
472 u32 dts;
|
eo301@0
|
473 u32 i;
|
eo301@0
|
474 u8 *TextSample;
|
eo301@0
|
475 MP4InputStreamPtr is;
|
eo301@0
|
476 u32 TextModifiersSize, TotalAtomSize;
|
eo301@0
|
477 MP4AtomPtr entry;
|
eo301@0
|
478 TextStyleAtomPtr styl;
|
eo301@0
|
479 TextHighlightAtomPtr hlit;
|
eo301@0
|
480 TextHighlightColorAtomPtr hclr;
|
eo301@0
|
481 TextKaraokeAtomPtr krok;
|
eo301@0
|
482 TextSampleEntryValue tx3g_value;
|
eo301@0
|
483
|
eo301@0
|
484
|
eo301@0
|
485 err = MP4TrackReaderGetNextAccessUnit(decoder->TimedTextTrackReader, decoder->TimedTextSampleH, &unitSize, &sampleFlags, &cts, &dts);
|
eo301@0
|
486
|
eo301@0
|
487 if ( err )
|
eo301@0
|
488 {
|
eo301@0
|
489 if ( err == MP4EOF )
|
eo301@0
|
490 {
|
eo301@0
|
491 *SampleData = NULL;
|
eo301@0
|
492 *SampleDataSize = 0;
|
eo301@0
|
493 *CurrentTime = 0;
|
eo301@0
|
494 return MP4EOF;
|
eo301@0
|
495 }
|
eo301@0
|
496 else
|
eo301@0
|
497 goto bail;
|
eo301@0
|
498 }
|
eo301@0
|
499
|
eo301@0
|
500 err = MP4TrackReaderGetTextSampleEntryValues(decoder->TimedTextTrackReader, &tx3g_value); if(err) goto bail;
|
eo301@0
|
501
|
eo301@0
|
502 #if 0 //only text
|
eo301@0
|
503 *CurrentTime = dts;
|
eo301@0
|
504 *SampleData = *decoder->TimedTextSampleH;
|
eo301@0
|
505 *SampleDataSize = unitSize;
|
eo301@0
|
506 #else
|
eo301@0
|
507 *CurrentTime = dts;
|
eo301@0
|
508 TextSample = *decoder->TimedTextSampleH;
|
eo301@0
|
509 *SampleDataSize = TextSample[0]<<8 | TextSample[1];
|
eo301@0
|
510 TextSample+=2;
|
eo301@0
|
511 MP4SetHandleSize(decoder->TextH, *SampleDataSize+1);
|
eo301@0
|
512 memcpy(*decoder->TextH, TextSample, *SampleDataSize);
|
eo301@0
|
513 TextSample += *SampleDataSize;
|
eo301@0
|
514 (*decoder->TextH)[*SampleDataSize] = '\0';
|
eo301@0
|
515 *SampleData = *decoder->TextH;
|
eo301@0
|
516
|
eo301@0
|
517 //Extract Text Style
|
eo301@0
|
518 InitTextSampleStyleParam(decoder->TextParam);
|
eo301@0
|
519 decoder->TextParam->displayFlags= tx3g_value.displayFlags;
|
eo301@0
|
520 decoder->TextParam->horizontal_justification= tx3g_value.horizontal_justification;
|
eo301@0
|
521 decoder->TextParam->vertical_justification= tx3g_value.vertical_justification;
|
eo301@0
|
522 decoder->TextParam->background_color_r= tx3g_value.background_color_r;
|
eo301@0
|
523 decoder->TextParam->background_color_g= tx3g_value.background_color_g;
|
eo301@0
|
524 decoder->TextParam->background_color_b= tx3g_value.background_color_b;
|
eo301@0
|
525 decoder->TextParam->background_color_a= tx3g_value.background_color_a;
|
eo301@0
|
526 decoder->TextParam->default_text_box_top= tx3g_value.default_text_box_top;
|
eo301@0
|
527 decoder->TextParam->default_text_box_left= tx3g_value.default_text_box_left;
|
eo301@0
|
528 decoder->TextParam->default_text_box_bottom= tx3g_value.default_text_box_bottom;
|
eo301@0
|
529 decoder->TextParam->default_text_box_right= tx3g_value.default_text_box_right;
|
eo301@0
|
530 decoder->TextParam->default_style_startChar= tx3g_value.default_style_startChar;
|
eo301@0
|
531 decoder->TextParam->default_style_endChar= tx3g_value.default_style_endChar;
|
eo301@0
|
532 decoder->TextParam->default_style_font_ID= tx3g_value.default_style_font_ID;
|
eo301@0
|
533 decoder->TextParam->default_style_face_style_flags= tx3g_value.default_style_face_style_flags;
|
eo301@0
|
534 decoder->TextParam->default_style_font_size= tx3g_value.default_style_font_size;
|
eo301@0
|
535 decoder->TextParam->default_style_text_color_r= tx3g_value.default_style_text_color_r;
|
eo301@0
|
536 decoder->TextParam->default_style_text_color_g= tx3g_value.default_style_text_color_g;
|
eo301@0
|
537 decoder->TextParam->default_style_text_color_b= tx3g_value.default_style_text_color_b;
|
eo301@0
|
538 decoder->TextParam->default_style_text_color_a= tx3g_value.default_style_text_color_a;
|
eo301@0
|
539 decoder->TextParam->font_ID= tx3g_value.font_ID;
|
eo301@0
|
540 decoder->TextParam->font_name_length= tx3g_value.font_name_length;
|
eo301@0
|
541 decoder->TextParam->font= _strdup(tx3g_value.font);
|
eo301@0
|
542 free(tx3g_value.font);
|
eo301@0
|
543
|
eo301@0
|
544 TotalAtomSize= 0;
|
eo301@0
|
545 TextModifiersSize = unitSize - 2 - *SampleDataSize;
|
eo301@0
|
546 err = MP4CreateMemoryInputStream(TextSample, TextModifiersSize, &is ); if (err) goto bail;
|
eo301@0
|
547 is->debugging = 0;
|
eo301@0
|
548 while(TextModifiersSize>TotalAtomSize)
|
eo301@0
|
549 {
|
eo301@0
|
550 err = MP4ParseAtom( is, &entry ); if (err) goto bail;
|
eo301@0
|
551 TotalAtomSize += entry->size;
|
eo301@0
|
552 if(entry->type == 'styl')
|
eo301@0
|
553 {
|
eo301@0
|
554 StyleRecordStructPtr styleRecord;
|
eo301@0
|
555 styl = (TextStyleAtomPtr)entry;
|
eo301@0
|
556 decoder->TextParam->styl_entry_count = styl->entry_count;
|
eo301@0
|
557 decoder->TextParam->styl_text_styles = (StyleRecord*)calloc(styl->entry_count, sizeof(styleRecord));
|
eo301@0
|
558 for(i=0; i<styl->entry_count; i++)
|
eo301@0
|
559 {
|
eo301@0
|
560 err = MP4GetListEntry(styl->styleRecordList, i, (char**)&styleRecord); if(err) goto bail;
|
eo301@0
|
561 memcpy(&decoder->TextParam->styl_text_styles[i], styleRecord, sizeof(StyleRecord));
|
eo301@0
|
562 }
|
eo301@0
|
563 }
|
eo301@0
|
564 else if(entry->type == 'hlit')
|
eo301@0
|
565 {
|
eo301@0
|
566 hlit = (TextHighlightAtomPtr)entry;
|
eo301@0
|
567 decoder->TextParam->hlit_startcharoffset = hlit->startcharoffset;
|
eo301@0
|
568 decoder->TextParam->hlit_endcharoffset = hlit->endcharoffset;
|
eo301@0
|
569 }
|
eo301@0
|
570 else if(entry->type == 'hclr')
|
eo301@0
|
571 {
|
eo301@0
|
572 hclr = (TextHighlightColorAtomPtr)entry;
|
eo301@0
|
573 decoder->TextParam->hclr_highlight_color_r = hclr->highlight_color_r;
|
eo301@0
|
574 decoder->TextParam->hclr_highlight_color_g = hclr->highlight_color_g;
|
eo301@0
|
575 decoder->TextParam->hclr_highlight_color_b = hclr->highlight_color_b;
|
eo301@0
|
576 decoder->TextParam->hclr_highlight_color_a = hclr->highlight_color_a;
|
eo301@0
|
577 }
|
eo301@0
|
578 else if(entry->type == 'krok')
|
eo301@0
|
579 {
|
eo301@0
|
580 krok = (TextKaraokeAtomPtr)entry;
|
eo301@0
|
581 decoder->TextParam->krok_highlight_start_time = krok->highlight_start_time;
|
eo301@0
|
582 decoder->TextParam->krok_entry_count = krok->entry_count;
|
eo301@0
|
583 decoder->TextParam->krok_highlight_end_time = calloc(krok->entry_count, sizeof(u32));
|
eo301@0
|
584 decoder->TextParam->krok_startcharoffset= calloc(krok->entry_count, sizeof(u32));
|
eo301@0
|
585 decoder->TextParam->krok_endcharoffset = calloc(krok->entry_count, sizeof(u32));
|
eo301@0
|
586 for(i=0; i<krok->entry_count; i++)
|
eo301@0
|
587 {
|
eo301@0
|
588 decoder->TextParam->krok_highlight_end_time[i] =krok->highlight_end_time[i];
|
eo301@0
|
589 decoder->TextParam->krok_startcharoffset[i] = krok->startcharoffset[i];
|
eo301@0
|
590 decoder->TextParam->krok_endcharoffset[i] = krok->endcharoffset[i];
|
eo301@0
|
591 }
|
eo301@0
|
592 }
|
eo301@0
|
593 else
|
eo301@0
|
594 {
|
eo301@0
|
595 BAILWITHERROR(MP4NotImplementedErr)
|
eo301@0
|
596 }
|
eo301@0
|
597
|
eo301@0
|
598 entry->destroy(entry);
|
eo301@0
|
599 }
|
eo301@0
|
600
|
eo301@0
|
601 if (is) {
|
eo301@0
|
602 is->destroy( is );
|
eo301@0
|
603 is = NULL;
|
eo301@0
|
604 }
|
eo301@0
|
605
|
eo301@0
|
606 *param = decoder->TextParam;
|
eo301@0
|
607 #endif
|
eo301@0
|
608
|
eo301@0
|
609 bail:
|
eo301@0
|
610 TEST_RETURN( err );
|
eo301@0
|
611 return err;
|
eo301@0
|
612 }
|
eo301@0
|
613
|
eo301@0
|
614 IMAF_DECODER_API IMAF_Err IMAFDecoder_GetDsiByIndex(IMAF_DecoderH IMafDecoder, unsigned int i, char** dsi, unsigned int *dsiSize)
|
eo301@0
|
615 {
|
eo301@0
|
616 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
617 IMAF_Err err;
|
eo301@0
|
618 MP4TrackReader reader;
|
eo301@0
|
619 MP4Handle specificInfoH;
|
eo301@0
|
620
|
eo301@0
|
621 err = MP4GetListEntry(decoder->TrackReaderList, i, (char**)&reader); if(err) goto bail;
|
eo301@0
|
622
|
eo301@0
|
623 err = MP4NewHandle(0, &specificInfoH); if(err) goto bail;
|
eo301@0
|
624 err = MP4TrackReaderGetCurrentDecoderSpecificInfo(reader, specificInfoH); if(err) goto bail;
|
eo301@0
|
625 err = MP4GetHandleSize(specificInfoH, dsiSize);
|
eo301@0
|
626 *dsi = (u8*)malloc(*dsiSize);
|
eo301@0
|
627 memcpy(*dsi, *specificInfoH, *dsiSize);
|
eo301@0
|
628 err = MP4DisposeHandle(specificInfoH); if(err) goto bail;
|
eo301@0
|
629
|
eo301@0
|
630 bail:
|
eo301@0
|
631 TEST_RETURN( err );
|
eo301@0
|
632 return err;
|
eo301@0
|
633 }
|
eo301@0
|
634
|
eo301@0
|
635 IMAF_DECODER_API IMAF_Err IMAFDecoder_GetSongImage(IMAF_DecoderH IMafDecoder, unsigned char **image, unsigned int *imageSize)
|
eo301@0
|
636 {
|
eo301@0
|
637 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
638 IMAF_Err err;
|
eo301@0
|
639 u8 *content_type;
|
eo301@0
|
640
|
eo301@0
|
641 err = MP4GetMovieIndTrack( decoder->moov, 1, &decoder->trak ); if (err) goto bail;
|
eo301@0
|
642 err = MP4GetTrackMedia( decoder->trak, &decoder->media ); if (err) goto bail;
|
eo301@0
|
643 err = MP4_GetImageByItemId(decoder->moov, decoder->media, image, imageSize, &content_type, 1); if(err) goto bail;
|
eo301@0
|
644
|
eo301@0
|
645 bail:
|
eo301@0
|
646 TEST_RETURN( err );
|
eo301@0
|
647 return err;
|
eo301@0
|
648 }
|
eo301@0
|
649
|
eo301@0
|
650 IMAF_DECODER_API IMAF_Err IMAFDecoder_GetMetadata(IMAF_DecoderH IMafDecoder, unsigned char **Meta, unsigned int *MetaSize)
|
eo301@0
|
651 {
|
eo301@0
|
652 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
653 IMAF_Err err;
|
eo301@0
|
654
|
eo301@0
|
655 err = MP4GetMetaXml(decoder->moov, Meta, MetaSize); if(err) goto bail;
|
eo301@0
|
656 bail:
|
eo301@0
|
657 TEST_RETURN( err );
|
eo301@0
|
658 return err;
|
eo301@0
|
659 }
|
eo301@0
|
660
|
eo301@0
|
661 IMAF_DECODER_API IMAF_Err IMAF_Decoder_Destroy(IMAF_DecoderH IMafDecoder)
|
eo301@0
|
662 {
|
eo301@0
|
663 IMAFDecoder *decoder = (IMAFDecoder*) IMafDecoder;
|
eo301@0
|
664 IMAF_Err err;
|
eo301@0
|
665
|
eo301@0
|
666 if(decoder)
|
eo301@0
|
667 {
|
eo301@0
|
668 if(decoder->InputMafFilename)
|
eo301@0
|
669 {
|
eo301@0
|
670 free(decoder->InputMafFilename);
|
eo301@0
|
671 decoder->InputMafFilename = NULL;
|
eo301@0
|
672 }
|
eo301@0
|
673
|
eo301@0
|
674 if(decoder->TrackReaderList)
|
eo301@0
|
675 {
|
eo301@0
|
676 u32 i;
|
eo301@0
|
677 MP4TrackReader reader;
|
eo301@0
|
678 MP4Handle sampleH;
|
eo301@0
|
679 for(i=0; i<decoder->TrackCount - decoder->HasTimedTextTrack; i++)
|
eo301@0
|
680 {
|
eo301@0
|
681 err = MP4GetListEntry(decoder->TrackReaderList, i, (char**)&reader); if(err) goto bail;
|
eo301@0
|
682 err = MP4DisposeTrackReader(reader); if(err) goto bail;
|
eo301@0
|
683 err = MP4GetListEntry(decoder->TrackSampleList, i, (char**)&sampleH); if(err) goto bail;
|
eo301@0
|
684 err = MP4DisposeHandle(sampleH); if(err) goto bail;
|
eo301@0
|
685 }
|
eo301@0
|
686 err = MP4DeleteLinkedList(decoder->TrackReaderList); if(err) goto bail;
|
eo301@0
|
687 err = MP4DeleteLinkedList(decoder->TrackSampleList); if(err) goto bail;
|
eo301@0
|
688 decoder->TrackReaderList = NULL;
|
eo301@0
|
689 decoder->TrackSampleList = NULL;
|
eo301@0
|
690 }
|
eo301@0
|
691
|
eo301@0
|
692 if(decoder->TimedTextSampleH)
|
eo301@0
|
693 MP4DisposeHandle(decoder->TimedTextSampleH);
|
eo301@0
|
694 if(decoder->TextH)
|
eo301@0
|
695 MP4DisposeHandle(decoder->TextH);
|
eo301@0
|
696 if(decoder->TimedTextTrackReader)
|
eo301@0
|
697 MP4DisposeTrackReader(decoder->TimedTextTrackReader);
|
eo301@0
|
698 if(decoder->TextParam)
|
eo301@0
|
699 {
|
eo301@0
|
700 InitTextSampleStyleParam(decoder->TextParam);
|
eo301@0
|
701 free(decoder->TextParam);
|
eo301@0
|
702 }
|
eo301@0
|
703
|
eo301@0
|
704 if(decoder->moov)
|
eo301@0
|
705 {
|
eo301@0
|
706 err = MP4DisposeMovie( decoder->moov ); if(err) goto bail;
|
eo301@0
|
707 }
|
eo301@0
|
708 free(decoder);
|
eo301@0
|
709 }
|
eo301@0
|
710
|
eo301@0
|
711 bail:
|
eo301@0
|
712 return err;
|
eo301@0
|
713 }
|
eo301@0
|
714
|
eo301@0
|
715 IMAF_DECODER_API char* IMAF_Decoder_GetLastError(IMAF_Err err)
|
eo301@0
|
716 {
|
eo301@0
|
717 return MP4GetLastError(err);
|
eo301@0
|
718 } |