📄 isom_read.c
字号:
trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !StreamDescriptionIndex) return NULL; entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1); //no entry or MPEG entry: if (!entry || IsMP4Description(entry->type) ) return NULL; //if we handle the description return false switch (entry->type) { case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: case GF_ISOM_SUBTYPE_3GP_H263: return NULL; case GF_ISOM_BOX_TYPE_GNRV: GF_SAFEALLOC(udesc, GF_GenericSampleDescription); if (entry->EntryType == GF_ISOM_BOX_TYPE_UUID) { memcpy(udesc->UUID, ((GF_UUIDBox*)entry)->uuid, sizeof(bin128)); } else { udesc->codec_tag = entry->EntryType; } udesc->version = entry->version; udesc->revision = entry->revision; udesc->vendor_code = entry->vendor; udesc->temporal_quality = entry->temporal_quality; udesc->spacial_quality = entry->spacial_quality; udesc->width = entry->Width; udesc->height = entry->Height; udesc->h_res = entry->horiz_res; udesc->v_res = entry->vert_res; strcpy(udesc->compressor_name, entry->compressor_name); udesc->depth = entry->bit_depth; udesc->color_table_index = entry->color_table_index; if (entry->data_size) { udesc->extension_buf_size = entry->data_size; udesc->extension_buf = (char*)malloc(sizeof(char) * entry->data_size); memcpy(udesc->extension_buf, entry->data, entry->data_size); } return udesc; case GF_ISOM_BOX_TYPE_GNRA: gena = (GF_GenericAudioSampleEntryBox *)entry; GF_SAFEALLOC(udesc, GF_GenericSampleDescription); if (gena->EntryType == GF_ISOM_BOX_TYPE_UUID) { memcpy(udesc->UUID, ((GF_UUIDBox*)gena)->uuid, sizeof(bin128)); } else { udesc->codec_tag = gena->EntryType; } udesc->version = gena->version; udesc->revision = gena->revision; udesc->vendor_code = gena->vendor; udesc->samplerate = gena->samplerate_hi; udesc->bits_per_sample = gena->bitspersample; udesc->nb_channels = gena->channel_count; if (gena->data_size) { udesc->extension_buf_size = gena->data_size; udesc->extension_buf = (char*)malloc(sizeof(char) * gena->data_size); memcpy(udesc->extension_buf, gena->data, gena->data_size); } return udesc; case GF_ISOM_BOX_TYPE_GNRM: genm = (GF_GenericSampleEntryBox *)entry; GF_SAFEALLOC(udesc, GF_GenericSampleDescription); if (genm->EntryType == GF_ISOM_BOX_TYPE_UUID) { memcpy(udesc->UUID, ((GF_UUIDBox*)genm)->uuid, sizeof(bin128)); } else { udesc->codec_tag = genm->EntryType; } if (genm->data_size) { udesc->extension_buf_size = genm->data_size; udesc->extension_buf = (char*)malloc(sizeof(char) * genm->data_size); memcpy(udesc->extension_buf, genm->data, genm->data_size); } return udesc; } return NULL;}GF_EXPORTGF_Err gf_isom_get_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, u32 *Width, u32 *Height){ GF_TrackBox *trak; GF_SampleEntryBox *entry; GF_SampleDescriptionBox *stsd; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; stsd = trak->Media->information->sampleTable->SampleDescription; if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE; if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) return movie->LastError = GF_BAD_PARAM; entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1); //no support for generic sample entries (eg, no MPEG4 descriptor) if (entry == NULL) return GF_BAD_PARAM; //valid for MPEG visual, JPG and 3GPP H263 switch (entry->type) { case GF_ISOM_BOX_TYPE_ENCV: case GF_ISOM_BOX_TYPE_MP4V: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_BOX_TYPE_AVC1: case GF_ISOM_BOX_TYPE_GNRV: *Width = ((GF_VisualSampleEntryBox*)entry)->Width; *Height = ((GF_VisualSampleEntryBox*)entry)->Height; return GF_OK; default: if (trak->Media->handler->handlerType==GF_ISOM_MEDIA_SCENE) { *Width = trak->Header->width>>16; *Height = trak->Header->height>>16; return GF_OK; } return GF_BAD_PARAM; }}GF_EXPORTGF_Err gf_isom_get_audio_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, u32 *SampleRate, u32 *Channels, u8 *bitsPerSample){ GF_TrackBox *trak; GF_SampleEntryBox *entry; GF_SampleDescriptionBox *stsd; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; stsd = trak->Media->information->sampleTable->SampleDescription; if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE; if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) return movie->LastError = GF_BAD_PARAM; entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1); //no support for generic sample entries (eg, no MPEG4 descriptor) if (entry == NULL) return GF_BAD_PARAM; switch (entry->type) { case GF_ISOM_BOX_TYPE_ENCA: if (entry->protection_info && (entry->protection_info->original_format->data_format!= GF_ISOM_BOX_TYPE_MP4A)) return GF_ISOM_INVALID_MEDIA; case GF_ISOM_BOX_TYPE_MP4A: case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: if (SampleRate) (*SampleRate) = ((GF_AudioSampleEntryBox*)entry)->samplerate_hi; if (Channels) (*Channels) = ((GF_AudioSampleEntryBox*)entry)->channel_count; if (bitsPerSample) (*bitsPerSample) = (u8) ((GF_AudioSampleEntryBox*)entry)->bitspersample; return GF_OK; default: return GF_BAD_PARAM; }}GF_EXPORTconst char *gf_isom_get_filename(GF_ISOFile *movie){ if (!movie) return NULL;#ifndef GPAC_READ_ONLY if (movie->finalName && !movie->fileName) return movie->finalName;#endif return movie->fileName;}GF_EXPORTu8 gf_isom_get_pl_indication(GF_ISOFile *movie, u8 PL_Code){ GF_IsomInitialObjectDescriptor *iod; if (!movie || !movie->moov) return 0; if (!movie->moov->iods || !movie->moov->iods->descriptor) return 0xFF; if (movie->moov->iods->descriptor->tag != GF_ODF_ISOM_IOD_TAG) return 0xFF; iod = (GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor; switch (PL_Code) { case GF_ISOM_PL_AUDIO: return iod->audio_profileAndLevel; case GF_ISOM_PL_VISUAL: return iod->visual_profileAndLevel; case GF_ISOM_PL_GRAPHICS: return iod->graphics_profileAndLevel; case GF_ISOM_PL_SCENE: return iod->scene_profileAndLevel; case GF_ISOM_PL_OD: return iod->OD_profileAndLevel; case GF_ISOM_PL_INLINE: return iod->inlineProfileFlag; case GF_ISOM_PL_MPEGJ: default: return 0xFF; }}GF_EXPORTGF_Err gf_isom_get_track_layout_info(GF_ISOFile *movie, u32 trackNumber, u32 *width, u32 *height, s32 *translation_x, s32 *translation_y, s16 *layer){ GF_TrackBox *tk = gf_isom_get_track_from_file(movie, trackNumber); if (!tk) return GF_BAD_PARAM; if (width) *width = tk->Header->width>>16; if (height) *height = tk->Header->height>>16; if (layer) *layer = tk->Header->layer; if (translation_x) *translation_x = tk->Header->matrix[6] >> 16; if (translation_y) *translation_y = tk->Header->matrix[7] >> 16; return GF_OK;}/*returns total amount of media bytes in track*/u64 gf_isom_get_media_data_size(GF_ISOFile *movie, u32 trackNumber){ u32 i, size; GF_SampleSizeBox *stsz; GF_TrackBox *tk = gf_isom_get_track_from_file(movie, trackNumber); if (!tk) return 0; stsz = tk->Media->information->sampleTable->SampleSize; if (stsz->sampleSize) return stsz->sampleSize*stsz->sampleCount; size = 0; for (i=0; i<stsz->sampleCount;i++) size += stsz->sizes[i]; return size;}GF_EXPORTvoid gf_isom_set_default_sync_track(GF_ISOFile *movie, u32 trackNumber){ GF_TrackBox *tk = gf_isom_get_track_from_file(movie, trackNumber); if (!tk) movie->es_id_default_sync = -1; else movie->es_id_default_sync = tk->Header->trackID;}GF_EXPORTBool gf_isom_is_single_av(GF_ISOFile *file){ u32 count, i, nb_any, nb_a, nb_v, nb_scene, nb_od, nb_text; nb_a = nb_v = nb_any = nb_scene = nb_od = nb_text = 0; if (!file->moov) return 0; count = gf_isom_get_track_count(file); for (i=0; i<count; i++) { u32 mtype = gf_isom_get_media_type(file, i+1); if (mtype==GF_ISOM_MEDIA_SCENE) { if (gf_isom_get_sample_count(file, i+1)>1) nb_any++; else nb_scene++; } else if (mtype==GF_ISOM_MEDIA_OD) { if (gf_isom_get_sample_count(file, i+1)>1) nb_any++; else nb_od++; } else if (mtype==GF_ISOM_MEDIA_TEXT) nb_text++; else if (mtype==GF_ISOM_MEDIA_AUDIO) nb_a++; else if (mtype==GF_ISOM_MEDIA_VISUAL) { /*discard file with images*/ if (gf_isom_get_sample_count(file, i+1)==1) nb_any++; else nb_v++; } else nb_any++; } if (nb_any) return 0; if ((nb_scene<=1) && (nb_od<=1) && (nb_a<=1) && (nb_v<=1) && (nb_text<=1) ) return 1; return 0;}GF_EXPORTBool gf_isom_is_JPEG2000(GF_ISOFile *mov){ return (mov && mov->is_jp2) ? 1 : 0;}GF_EXPORTu32 gf_isom_guess_specification(GF_ISOFile *file){ u32 count, i, nb_any, nb_m4s, nb_a, nb_v, nb_scene, nb_od, nb_mp3, nb_aac, nb_m4v, nb_avc, nb_amr, nb_h263, nb_qcelp, nb_evrc, nb_smv, nb_text; nb_m4s = nb_a = nb_v = nb_any = nb_scene = nb_od = nb_mp3 = nb_aac = nb_m4v = nb_avc = nb_amr = nb_h263 = nb_qcelp = nb_evrc = nb_smv = nb_text = 0; if (file->is_jp2) { if (file->moov) return GF_4CC('m','j','p','2'); return GF_4CC('j','p','2',' '); } if (!file->moov) { if (!file->meta || !file->meta->handler) return 0; return file->meta->handler->handlerType; } count = gf_isom_get_track_count(file); for (i=0; i<count; i++) { u32 mtype = gf_isom_get_media_type(file, i+1); u32 mstype = gf_isom_get_media_subtype(file, i+1, 1); if (mtype==GF_ISOM_MEDIA_SCENE) { nb_scene++; /*forces non-isma*/ if (gf_isom_get_sample_count(file, i+1)>1) nb_m4s++; } else if (mtype==GF_ISOM_MEDIA_OD) { nb_od++; /*forces non-isma*/ if (gf_isom_get_sample_count(file, i+1)>1) nb_m4s++; } else if (mtype==GF_ISOM_MEDIA_TEXT) nb_text++; else if ((mtype==GF_ISOM_MEDIA_AUDIO) || (mtype==GF_ISOM_MEDIA_VISUAL)) { switch (mstype) { case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: nb_amr++; break; case GF_ISOM_SUBTYPE_3GP_H263: nb_h263++; break; case GF_ISOM_SUBTYPE_3GP_EVRC: nb_evrc++; break; case GF_ISOM_SUBTYPE_3GP_QCELP: nb_qcelp++; break; case GF_ISOM_SUBTYPE_3GP_SMV: nb_smv++; break; case GF_ISOM_SUBTYPE_AVC_H264: nb_avc++; break; case GF_ISOM_SUBTYPE_MPEG4: case GF_ISOM_SUBTYPE_MPEG4_CRYP: { GF_DecoderConfig *dcd = gf_isom_get_decoder_config(file, i+1, 1); switch (dcd->streamType) { case 0x04: if (dcd->objectTypeIndication==0x20) nb_m4v++; else if (dcd->objectTypeIndication==0x21) nb_avc++; else nb_v++; break; case 0x05: switch (dcd->objectTypeIndication) { case 0x66: case 0x67: case 0x68: case 0x40: nb_aac++; break; case 0x69: case 0x6B: nb_mp3++; break; case 0xA0: nb_evrc++; break; case 0xA1: nb_smv++; break; case 0xE1: nb_qcelp++; break; default: nb_a++; break; } break; /*SHOULD NEVER HAPPEN - IF SO, BROKEN MPEG4 FILE*/ default: nb_any++; break; } gf_odf_desc_del((GF_Descriptor *)dcd); } break; default: if (mtype==GF_ISOM_MEDIA_VISUAL) nb_v++; else nb_a++; break; } } else if ((mtype==GF_ISOM_SUBTYPE_MPEG4) || (mtype==GF_ISOM_SUBTYPE_MPEG4_CRYP)) nb_m4s++; else nb_any++; } if (nb_any) return GF_ISOM_BRAND_ISOM; if (nb_qcelp || nb_evrc || nb_smv) { /*non std mix of streams*/ if (nb_m4s || nb_avc || nb_scene || nb_od || nb_mp3 || nb_a || nb_v) return GF_ISOM_BRAND_ISOM; return GF_ISOM_BRAND_3G2A; } /*other a/v/s streams*/ if (nb_v || nb_a || nb_m4s) return GF_ISOM_BRAND_MP42; nb_v = nb_m4v + nb_avc + nb_h263; nb_a = nb_mp3 + nb_aac + nb_amr; /*avc file: whatever has AVC and no systems*/ if (nb_avc) { if (!nb_scene && !nb_od) return GF_ISOM_BRAND_AVC1; return GF_ISOM_BRAND_MP42; } /*MP3: ISMA and MPEG4*/ if (nb_mp3) { if (!nb_text && (nb_v<=1) && (nb_a<=1) && (nb_scene==1) && (nb_od==1)) return GF_4CC('I', 'S', 'M', 'A'); return GF_ISOM_BRAND_MP42; } /*MP4*/ if (nb_scene || nb_od) { /*issue with AMR and H263 which don't have MPEG mapping: non compliant file*/ if (nb_amr || nb_h263) return GF_ISOM_BRAND_ISOM; return GF_ISOM_BRAND_MP42; } /*use ISMA (3GP fine too)*/ if (!nb_amr && !nb_h263 && !nb_text) { if ((nb_v<=1) && (nb_a<=1)) return GF_4CC('I', 'S', 'M', 'A'); return GF_ISOM_BRAND_MP42; } if ((nb_v<=1) && (nb_a<=1) && (nb_text<=1)) return nb_text ? GF_ISOM_BRAND_3GP6 : GF_ISOM_BRAND_3GP5; return GF_ISOM_BRAND_3GG6;}GF_ItemListBox *gf_ismo_locate_box(GF_List *list, u32 boxType, bin128 UUID){ u32 i; GF_Box *box; i=0; while ((box = (GF_Box *)gf_list_enum(list, &i))) { if (box->type == boxType) { GF_UUIDBox* box2 = (GF_UUIDBox* )box; if (boxType != GF_ISOM_BOX_TYPE_UUID) return (GF_ItemListBox *)box; if (!memcmp(box2->uuid, UUID, 16)) return (GF_ItemListBox *)box; } } return NULL;}/*Apple extensions*/GF_EXPORTGF_Err gf_isom_apple_get_tag(GF_ISOFile *mov, u32 tag, const char **data, u32 *data_len){ u32 i; GF_ListItemBox *info; GF_ItemListBox *ilst; GF_MetaBox *meta; *data = NULL; *data_len = 0; meta = gf_isom_apple_get_meta_extensions(mov); if (!meta) return GF_URL_ERROR; ilst = gf_ismo_locate_box(meta->other_boxes, GF_ISOM_BOX_TYPE_ILST, NULL); if (!ilst) return GF_URL_ERROR; if (tag==GF_ISOM_ITUNE_PROBE) return GF_OK; i=0; while ( (info=gf_list_enum(ilst->tags, &i))) { if (info->type==tag) break; /*special cases*/ if ((tag==GF_ISOM_ITUNE_GENRE) && (info->type==GF_ISOM_BOX_TYPE_0xA9GEN)) break; info = NULL; } if (!info || !info->data || !info->data->data) return GF_URL_ERROR; if ((tag == GF_ISOM_ITUNE_GENRE) && (info->data->flags == 0)) { if (info->data->dataSize && (info->data->dataSize>2) && (info->data->dataSize < 5)) { GF_BitStream* bs = gf_bs_new(info->data->data, info->data->dataSize, GF_BITSTREAM_READ); *data_len = gf_bs_read_int(bs, info->data->dataSize * 8); gf_bs_del(bs); return GF_OK; } }// if (info->data->flags != 0x1) return GF_URL_ERROR; *data = info->data->data; *data_len = info->data->dataSize; if ((tag==GF_ISOM_ITUNE_COVER_ART) && (info->data->flags==14)) *data_len |= (1<<31); return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -