annotate 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
rev   line source
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, &param->MajorBrand, &minorVersion); if(err) goto bail;
eo301@0 132 err = ISOGetNbCompatableBrands(decoder->moov, &param->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, &timescale); 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 }