comparison IM_AF Decoder/IM_AF_Decoder.c @ 0:138a3cea9792

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