📄 isom_tools.c
字号:
samp->data = NULL; gf_isom_sample_del(&samp); gf_isom_set_track_group(mp4file, bifsT, 1); gf_isom_set_track_enabled(mp4file, bifsT, 1); gf_isom_set_track_enabled(mp4file, odT, 1); gf_isom_add_track_to_root_od(mp4file, bifsT); gf_isom_add_track_to_root_od(mp4file, odT); gf_isom_set_pl_indication(mp4file, GF_ISOM_PL_SCENE, 1); gf_isom_set_pl_indication(mp4file, GF_ISOM_PL_GRAPHICS, 1); gf_isom_set_pl_indication(mp4file, GF_ISOM_PL_OD, 1); gf_isom_set_pl_indication(mp4file, GF_ISOM_PL_AUDIO, audioPL); gf_isom_set_pl_indication(mp4file, GF_ISOM_PL_VISUAL, (u8) (is_image ? 0xFE : visualPL)); gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_MP42, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_ISOM, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 1); return GF_OK;}GF_EXPORTGF_Err gf_media_make_3gpp(GF_ISOFile *mp4file){ u32 Tracks, i, mType, stype, nb_vid, nb_avc, nb_aud, nb_txt, nb_non_mp4; Bool is_3g2 = 0; switch (gf_isom_get_mode(mp4file)) { case GF_ISOM_OPEN_EDIT: case GF_ISOM_OPEN_WRITE: case GF_ISOM_WRITE_EDIT: break; default: return GF_BAD_PARAM; } Tracks = gf_isom_get_track_count(mp4file); nb_vid = nb_aud = nb_txt = nb_avc = nb_non_mp4 = 0; for (i=0; i<Tracks; i++) { gf_isom_remove_track_from_root_od(mp4file, i+1); mType = gf_isom_get_media_type(mp4file, i+1); switch (mType) { case GF_ISOM_MEDIA_VISUAL: /*remove image tracks if wanted*/ if (gf_isom_get_sample_count(mp4file, i+1)<=1) { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Visual track ID %d: only one sample found, assuming image and removing track\n", gf_isom_get_track_id(mp4file, i+1) )); goto remove_track; } stype = gf_isom_get_media_subtype(mp4file, i+1, 1); if (stype == GF_ISOM_SUBTYPE_MPEG4_CRYP) gf_isom_get_ismacryp_info(mp4file, i+1, 1, &stype, NULL, NULL, NULL, NULL, NULL, NULL, NULL); switch (stype) { case GF_ISOM_SUBTYPE_3GP_H263: nb_vid++; nb_non_mp4 ++; break; case GF_ISOM_SUBTYPE_AVC_H264: nb_vid++; nb_avc++; break; case GF_ISOM_SUBTYPE_MPEG4: { GF_ESD *esd = gf_isom_get_esd(mp4file, i+1, 1); /*both MPEG4-Video and H264/AVC are supported*/ if ((esd->decoderConfig->objectTypeIndication==0x20) || (esd->decoderConfig->objectTypeIndication==0x21) ) { nb_vid++; } else { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Video format not supported by 3GP - removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); goto remove_track; } gf_odf_desc_del((GF_Descriptor *)esd); } break; default: GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Video format not supported by 3GP - removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); goto remove_track; } break; case GF_ISOM_MEDIA_AUDIO: stype = gf_isom_get_media_subtype(mp4file, i+1, 1); if (stype == GF_ISOM_SUBTYPE_MPEG4_CRYP) gf_isom_get_ismacryp_info(mp4file, i+1, 1, &stype, NULL, NULL, NULL, NULL, NULL, NULL, NULL); switch (stype) { case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: is_3g2 = 1; nb_aud++; break; case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: nb_aud++; nb_non_mp4 ++; break; case GF_ISOM_SUBTYPE_MPEG4: { GF_ESD *esd = gf_isom_get_esd(mp4file, i+1, 1); switch (esd->decoderConfig->objectTypeIndication) { case 0xE1: case 0xA0: case 0xA1: is_3g2 = 1; case 0x40: nb_aud++; break; default: GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Audio format not supported by 3GP - removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); goto remove_track; } gf_odf_desc_del((GF_Descriptor *)esd); } break; default: GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Audio format not supported by 3GP - removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); goto remove_track; } break; case GF_ISOM_MEDIA_TEXT: nb_txt++; break; /*clean file*/ default: if (mType==GF_ISOM_MEDIA_HINT) { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Removing Hint track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); } else { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Removing system track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); }remove_track: gf_isom_remove_track(mp4file, i+1); i -= 1; Tracks = gf_isom_get_track_count(mp4file); break; } } /*no more IOD*/ gf_isom_remove_root_od(mp4file); if (is_3g2) { gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_3G2A, 65536); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP6, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GG6, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP2\n")); } else { /*update FType*/ if ((nb_vid>1) || (nb_aud>1) || (nb_txt>1)) { /*3GPP general purpose*/ gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_3GG6, 1024); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP6, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP4, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP Generic file\n")); } /*commented for QT compatibility, although this is correct (qt doesn't understand 3GP6 brand)*/ else if (nb_txt && 0) { gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_3GP6, 1024); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP4, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GG6, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP V6 file\n")); } else if (nb_avc) { gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_3GP6, 0/*1024*/); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_AVC1, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP4, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP V6 file + AVC compatible\n")); } else { gf_isom_set_brand_info(mp4file, nb_avc ? GF_ISOM_BRAND_3GP6 : GF_ISOM_BRAND_3GP5, 0/*1024*/); gf_isom_modify_alternate_brand(mp4file, nb_avc ? GF_ISOM_BRAND_3GP5 : GF_ISOM_BRAND_3GP6, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP4, 1); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GG6, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP V5 file\n")); } } /*add/remove MP4 brands and add isom*/ gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_MP41, (u8) ((nb_avc||is_3g2||nb_non_mp4) ? 0 : 1)); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_MP42, (u8) (nb_non_mp4 ? 0 : 1)); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_ISOM, 1); return GF_OK;}GF_Err gf_media_make_psp(GF_ISOFile *mp4){ u32 i, count; u32 nb_a, nb_v; /*psp track UUID*/ bin128 psp_track_uuid = {0x55, 0x53, 0x4D, 0x54, 0x21, 0xD2, 0x4F, 0xCE, 0xBB, 0x88, 0x69, 0x5C, 0xFA, 0xC9, 0xC7, 0x40}; u8 psp_track_sig [] = {0x00, 0x00, 0x00, 0x1C, 0x4D, 0x54, 0x44, 0x54, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0A, 0x55, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}; /*psp mov UUID*/ //bin128 psp_uuid = {0x50, 0x52, 0x4F, 0x46, 0x21, 0xD2, 0x4F, 0xCE, 0xBB, 0x88, 0x69, 0x5C, 0xFA, 0xC9, 0xC7, 0x40}; nb_a = nb_v = 0; count = gf_isom_get_track_count(mp4); for (i=0; i<count; i++) { switch (gf_isom_get_media_type(mp4, i+1)) { case GF_ISOM_MEDIA_VISUAL: nb_v++; break; case GF_ISOM_MEDIA_AUDIO: nb_a++; break; } } if ((nb_v != 1) && (nb_a!=1)) { GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[PSP convert] Movies need one audio track and one video track\n" )); return GF_BAD_PARAM; } for (i=0; i<count; i++) { switch (gf_isom_get_media_type(mp4, i+1)) { case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_AUDIO: /*if no edit list, add one*/ if (!gf_isom_get_edit_segment_count(mp4, i+1)) { gf_isom_remove_edit_segments(mp4, i+1); gf_isom_append_edit_segment(mp4, i+1, gf_isom_get_track_duration(mp4, i+1), 0, GF_ISOM_EDIT_NORMAL); } /*add PSP UUID*/ gf_isom_remove_uuid(mp4, i+1, psp_track_uuid); gf_isom_add_uuid(mp4, i+1, psp_track_uuid, (char *) psp_track_sig, 28); break; default: GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[PSP convert] Removing track ID %d\n", gf_isom_get_track_id(mp4, i+1) )); gf_isom_remove_track(mp4, i+1); i -= 1; count -= 1; break; } } gf_isom_set_brand_info(mp4, GF_4CC('M','S','N','V'), 0); gf_isom_modify_alternate_brand(mp4, GF_4CC('M','S','N','V'), 1); return GF_OK;}typedef struct{ u32 TrackID; u32 SampleNum, SampleCount; u32 FragmentLength; u32 OriginalTrack; u32 TimeScale, MediaType, DefaultDuration;} TrackFragmenter;GF_EXPORTGF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration){ u8 NbBits; u32 i, TrackNum, descIndex, j, count; u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, nb_samp, nb_done; u8 defaultPadding; u16 defaultDegradationPriority; GF_Err e; const char *tag; u32 tag_len; GF_ESD *esd; GF_ISOFile *output; GF_ISOSample *sample, *next; GF_List *fragmenters; u32 MaxFragmentDuration; TrackFragmenter *tf; //create output file output = gf_isom_open(output_file, GF_ISOM_OPEN_WRITE, NULL); if (!output) return gf_isom_last_error(NULL); nb_samp = 0; fragmenters = gf_list_new(); /*FIXME - ALL THESE SHOULD GO DO A clone_movie item !!*/ e = gf_isom_set_brand_info(output, GF_ISOM_BRAND_MP42, 1); if (e) goto err_exit; e = gf_isom_modify_alternate_brand(output, GF_ISOM_BRAND_ISOM, 1); if (e) goto err_exit; //copy movie desc gf_isom_clone_root_od(input, output); //clone copyright count = gf_isom_get_copyright_count(input); if (count) { const char *lang, *note; for (i=0; i<count; i++) { gf_isom_get_copyright(input, i+1, &lang, ¬e); gf_isom_set_copyright(output, (char *)lang, (char *)note); } } count = gf_isom_get_chapter_count(input, 0); if (count) { const char *name; u64 time; for (i=0; i<count; i++) { gf_isom_get_chapter(input, 0, i+1, &time, &name); gf_isom_add_chapter(output, 0, time, (char *)name); } } if (gf_isom_apple_get_tag(input, 0, &tag, &tag_len) == GF_OK) { for (i=GF_ISOM_ITUNE_ALBUM; i<GF_ISOM_ITUNE_WRITER; i++) { if (gf_isom_apple_get_tag(input, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) gf_isom_apple_set_tag(output, GF_ISOM_ITUNE_NAME, tag, tag_len); } } MaxFragmentDuration = (u32) (max_duration * 1000); //duplicates all tracks for (i=0; i<gf_isom_get_track_count(input); i++) { TrackNum = gf_isom_new_track(output, gf_isom_get_track_id(input, i+1), gf_isom_get_media_type(input, i+1), gf_isom_get_media_timescale(input, i+1)); if (!TrackNum) { e = gf_isom_last_error(output); goto err_exit; } esd = gf_isom_get_esd(input, i+1, 1); if (esd) { gf_isom_new_mpeg4_description(output, TrackNum, esd, NULL, NULL, &descIndex); gf_odf_desc_del((GF_Descriptor *) esd); } else { gf_isom_clone_sample_description(output, TrackNum, input, i+1, 1, NULL, NULL, &descIndex); } //if few samples don't fragment track count = gf_isom_get_sample_count(input, i+1); if (count<=2) { for (j=0; j<count; j++) { sample = gf_isom_get_sample(input, i+1, j+1, &descIndex); e = gf_isom_add_sample(output, TrackNum, 1, sample); gf_isom_sample_del(&sample); if (e) goto err_exit; } } //otherwise setup fragmented else { gf_isom_get_fragment_defaults(input, i+1, &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority); //otherwise setup fragmentation e = gf_isom_setup_track_fragment(output, gf_isom_get_track_id(output, TrackNum), defaultDescriptionIndex, defaultDuration, defaultSize, (u8) defaultRandomAccess, defaultPadding, defaultDegradationPriority); if (e) goto err_exit; GF_SAFEALLOC(tf, TrackFragmenter); tf->TrackID = gf_isom_get_track_id(output, TrackNum); tf->SampleCount = gf_isom_get_sample_count(input, i+1); tf->OriginalTrack = i+1; tf->TimeScale = gf_isom_get_media_timescale(input, i+1); tf->MediaType = gf_isom_get_media_type(input, i+1); tf->DefaultDuration = defaultDuration; gf_list_add(fragmenters, tf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -