📄 isom_tools.c
字号:
nb_samp += count; } if (gf_isom_is_track_in_root_od(input, i+1)) gf_isom_add_track_to_root_od(output, TrackNum); //copy user data ? } //flush movie e = gf_isom_finalize_for_fragment(output); if (e) goto err_exit; nb_done = 0; while ( (count = gf_list_count(fragmenters)) ) { e = gf_isom_start_fragment(output); if (e) goto err_exit; //setup some default for (i=0; i<count; i++) { tf = (TrackFragmenter *)gf_list_get(fragmenters, i); if (tf->MediaType == GF_ISOM_MEDIA_VISUAL) { e = gf_isom_set_fragment_option(output, tf->TrackID, GF_ISOM_TRAF_RANDOM_ACCESS, 1); if (e) goto err_exit; } } sample = NULL; //process track by track for (i=0; i<count; i++) { tf = (TrackFragmenter *)gf_list_get(fragmenters, i); //ok write samples while (1) { if (!sample) { sample = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 1, &descIndex); } gf_isom_get_sample_padding_bits(input, tf->OriginalTrack, tf->SampleNum+1, &NbBits); next = gf_isom_get_sample(input, tf->OriginalTrack, tf->SampleNum + 2, &j); if (next) { defaultDuration = (u32) (next->DTS - sample->DTS); } else { defaultDuration = tf->DefaultDuration; } e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex, defaultDuration, NbBits, 0); if (e) goto err_exit; gf_set_progress("ISO File Fragmenting", nb_done, nb_samp); nb_done++; gf_isom_sample_del(&sample); sample = next; tf->FragmentLength += defaultDuration; tf->SampleNum += 1; //end of track fragment or track if ((tf->SampleNum==tf->SampleCount) || (tf->FragmentLength*1000 > MaxFragmentDuration*tf->TimeScale)) { gf_isom_sample_del(&next); sample = next = NULL; tf->FragmentLength = 0; break; } } if (tf->SampleNum==tf->SampleCount) { free(tf); gf_list_rem(fragmenters, i); i--; count --; } } }err_exit: while (gf_list_count(fragmenters)) { tf = (TrackFragmenter *)gf_list_get(fragmenters, 0); free(tf); gf_list_rem(fragmenters, 0); } gf_list_del(fragmenters); if (e) gf_isom_delete(output); else gf_isom_close(output); gf_set_progress("ISO File Fragmenting", nb_samp, nb_samp); return e;}GF_EXPORTGF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps){ GF_Err e; u32 state; u32 cur_chap; u64 ts; u32 h, m, s, ms, fr, fps; char line[1024]; char szTitle[1024]; FILE *f = fopen(chap_file, "rt"); if (!f) return GF_URL_ERROR; e = gf_isom_remove_chapter(file, 0, 0); if (e) goto err_exit; cur_chap = 0; ts = 0; state = 0; while (fgets(line, 1024, f) != NULL) { char *title = NULL; u32 off = 0; char *sL; while (1) { u32 len = strlen(line); if (!len) break; switch (line[len-1]) { case '\n': case '\t': case '\r': case ' ': line[len-1] = 0; continue; } break; } while (line[off]==' ') off++; if (!strlen(line+off)) continue; sL = line+off; szTitle[0] = 0; /*ZoomPlayer chapters*/ if (!strnicmp(sL, "AddChapter(", 11)) { u32 nb_fr; sscanf(sL, "AddChapter(%d,%s)", &nb_fr, szTitle); ts = nb_fr; ts *= 1000; if (import_fps) ts = (u64) (((s64) ts ) / import_fps); else ts /= 25; sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0; } else if (!strnicmp(sL, "AddChapterBySecond(", 19)) { u32 nb_s; sscanf(sL, "AddChapterBySecond(%d,%s)", &nb_s, szTitle); ts = nb_s; ts *= 1000; sL = strchr(sL, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0; } else if (!strnicmp(sL, "AddChapterByTime(", 17)) { u32 h, m, s; sscanf(sL, "AddChapterByTime(%d,%d,%d,%s)", &h, &m, &s, szTitle); ts = 3600*h + 60*m + s; ts *= 1000; sL = strchr(sL, ','); if (sL) sL = strchr(sL+1, ','); if (sL) sL = strchr(sL+1, ','); strcpy(szTitle, sL+1); sL = strrchr(szTitle, ')'); if (sL) sL[0] = 0; } /*regular or SMPTE time codes*/ else if ((strlen(sL)>=8) && (sL[2]==':') && (sL[5]==':')) { title = NULL; if (strlen(sL)==8) { sscanf(sL, "%02d:%02d:%02d", &h, &m, &s); ts = (h*3600 + m*60+s)*1000; } else { char szTS[20], *tok; strncpy(szTS, sL, 18); tok = strrchr(szTS, ' '); if (tok) { title = strchr(sL, ' ') + 1; while (title[0]==' ') title++; if (strlen(title)) strcpy(szTitle, title); tok[0] = 0; } ts = 0; h = m = s = ms = 0; if (sscanf(szTS, "%d:%d:%d;%d/%d", &h, &m, &s, &fr, &fps)==5) { ts = (h*3600 + m*60+s)*1000 + 1000*fr/fps; } else if (sscanf(szTS, "%d:%d:%d;%d", &h, &m, &s, &fr)==4) { ts = (h*3600 + m*60+s); if (import_fps) ts = (s64) (((import_fps*((s64)ts) + fr) * 1000 ) / import_fps); else ts = ((ts*25 + fr) * 1000 ) / 25; } else if (sscanf(szTS, "%d:%d:%d.%d", &h, &m, &s, &ms) == 4) { ts = (h*3600 + m*60+s)*1000+ms; } else if (sscanf(szTS, "%d:%d:%d.%d", &h, &m, &s, &ms) == 4) { ts = (h*3600 + m*60+s)*1000+ms; } else if (sscanf(szTS, "%d:%d:%d:%d", &h, &m, &s, &ms) == 4) { ts = (h*3600 + m*60+s)*1000+ms; } else if (sscanf(szTS, "%d:%d:%d", &h, &m, &s) == 3) { ts = (h*3600 + m*60+s) * 1000; } } } /*CHAPTERX= and CHAPTERXNAME=*/ else if (!strnicmp(sL, "CHAPTER", 7)) { u32 idx; char szTemp[20], *str; strncpy(szTemp, sL, 19); str = strrchr(szTemp, '='); if (!str) continue; str[0] = 0; strlwr(szTemp); idx = cur_chap; str = strchr(sL, '='); str++; if (strstr(szTemp, "name")) { sscanf(szTemp, "chapter%dname", &idx); strcpy(szTitle, str); if (idx!=cur_chap) { cur_chap=idx; state = 0; } state++; } else { sscanf(szTemp, "chapter%d", &idx); if (idx!=cur_chap) { cur_chap=idx; state = 0; } state++; ts = 0; h = m = s = ms = 0; if (sscanf(str, "%d:%d:%d.%d", &h, &m, &s, &ms) == 4) { ts = (h*3600 + m*60+s)*1000+ms; } else if (sscanf(str, "%d:%d:%d:%d", &h, &m, &s, &ms) == 4) { ts = (h*3600 + m*60+s)*1000+ms; } else if (sscanf(str, "%d:%d:%d", &h, &m, &s) == 3) { ts = (h*3600 + m*60+s) * 1000; } } if (state==2) { e = gf_isom_add_chapter(file, 0, ts, szTitle); if (e) goto err_exit; state = 0; } continue; } else continue; if (strlen(szTitle)) { e = gf_isom_add_chapter(file, 0, ts, szTitle); } else { e = gf_isom_add_chapter(file, 0, ts, NULL); } if (e) goto err_exit; }err_exit: fclose(f); return e;}#endif //GPAC_READ_ONLYGF_EXPORTGF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track){ u32 type; GF_GenericSampleDescription *udesc; GF_BitStream *bs; GF_ESD *esd; u32 subtype = gf_isom_get_media_subtype(mp4, track, 1); /*all types with an official MPEG-4 mapping*/ switch (subtype) { case GF_ISOM_SUBTYPE_MPEG4: case GF_ISOM_SUBTYPE_MPEG4_CRYP: case GF_ISOM_SUBTYPE_AVC_H264: case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: return gf_isom_get_esd(mp4, track, 1); } if (gf_isom_get_media_type(mp4, track) == GF_ISOM_MEDIA_TEXT) return gf_isom_get_esd(mp4, track, 1); if ((subtype == GF_ISOM_SUBTYPE_3GP_AMR) || (subtype == GF_ISOM_SUBTYPE_3GP_AMR_WB)) { GF_3GPConfig *gpc = gf_isom_3gp_config_get(mp4, track, 1); esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = gf_isom_get_media_timescale(mp4, track); esd->ESID = gf_isom_get_track_id(mp4, track); esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_AUDIO; /*use private DSI*/ esd->decoderConfig->objectTypeIndication = GPAC_EXTRA_CODECS_OTI; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*format ext*/ gf_bs_write_u32(bs, subtype); gf_bs_write_u16(bs, (subtype == GF_ISOM_SUBTYPE_3GP_AMR) ? 8000 : 16000); gf_bs_write_u16(bs, (subtype == GF_ISOM_SUBTYPE_3GP_AMR) ? 160 : 320); gf_bs_write_u8(bs, 1); gf_bs_write_u8(bs, 16); gf_bs_write_u8(bs, gpc ? gpc->frames_per_sample : 0); if (gpc) free(gpc); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return esd; } if (subtype == GF_ISOM_SUBTYPE_3GP_H263) { u32 w, h; esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = gf_isom_get_media_timescale(mp4, track); esd->ESID = gf_isom_get_track_id(mp4, track); esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; /*use private DSI*/ esd->decoderConfig->objectTypeIndication = GPAC_EXTRA_CODECS_OTI; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*format ext*/ gf_bs_write_u32(bs, GF_4CC('h', '2', '6', '3')); gf_isom_get_visual_info(mp4, track, 1, &w, &h); gf_bs_write_u16(bs, w); gf_bs_write_u16(bs, h); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return esd; } type = gf_isom_get_media_type(mp4, track); if ((type != GF_ISOM_MEDIA_AUDIO) && (type != GF_ISOM_MEDIA_VISUAL)) return NULL; esd = gf_odf_desc_esd_new(0); esd->OCRESID = esd->ESID = gf_isom_get_track_id(mp4, track); esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = gf_isom_get_media_timescale(mp4, track); esd->decoderConfig->objectTypeIndication = GPAC_EXTRA_CODECS_OTI; /*format ext*/ bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, subtype); udesc = gf_isom_get_generic_sample_description(mp4, track, 1); if (type==GF_ISOM_MEDIA_AUDIO) { esd->decoderConfig->streamType = GF_STREAM_AUDIO; gf_bs_write_u16(bs, udesc->samplerate); gf_bs_write_u16(bs, 0); gf_bs_write_u8(bs, udesc->nb_channels); gf_bs_write_u8(bs, udesc->bits_per_sample); gf_bs_write_u8(bs, 0); } else { esd->decoderConfig->streamType = GF_STREAM_VISUAL; gf_bs_write_u16(bs, udesc->width); gf_bs_write_u16(bs, udesc->height); } if (udesc && udesc->extension_buf_size) { gf_bs_write_data(bs, udesc->extension_buf, udesc->extension_buf_size); free(udesc->extension_buf); } if (udesc) free(udesc); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return esd;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -