📄 filedump.c
字号:
} else if (mtype==GF_ISOM_MEDIA_FLASH) { fprintf(stdout, "Macromedia Flash Movie\n"); } else if (mtype==GF_ISOM_MEDIA_TEXT) { u32 w, h; s16 l; s32 tx, ty; gf_isom_get_track_layout_info(file, trackNum, &w, &h, &tx, &ty, &l); fprintf(stdout, "3GPP/MPEG-4 Timed Text - Size %d x %d - Translation X=%d Y=%d - Layer %d\n", w, h, tx, ty, l); } else { GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(file, trackNum, 1); if (udesc) { if (mtype==GF_ISOM_MEDIA_VISUAL) { fprintf(stdout, "Visual Track - Compressor \"%s\" - Resolution %d x %d\n", udesc->compressor_name, udesc->width, udesc->height); } else if (mtype==GF_ISOM_MEDIA_AUDIO) { fprintf(stdout, "Audio Track - Sample Rate %d - %d channel(s)\n", udesc->samplerate, udesc->nb_channels); } else { fprintf(stdout, "Unknown media type\n"); } fprintf(stdout, "\tVendor code \"%s\" - Version %d - revision %d\n", gf_4cc_to_str(udesc->vendor_code), udesc->version, udesc->revision); if (udesc->extension_buf) { fprintf(stdout, "\tCodec configuration data size: %d bytes\n", udesc->extension_buf_size); free(udesc->extension_buf); } free(udesc); } else { fprintf(stdout, "Unknown track type\n"); } } DumpMetaItem(file, 0, trackNum, "Track Meta"); if (!full_dump) { fprintf(stdout, "\n"); return; } dur = size = 0; max_rate = rate = 0; time_slice = 0; ts = gf_isom_get_media_timescale(file, trackNum); for (j=0; j<gf_isom_get_sample_count(file, trackNum); j++) { GF_ISOSample *samp = gf_isom_get_sample_info(file, trackNum, j+1, NULL, NULL); dur = samp->DTS+samp->CTS_Offset; size += samp->dataLength; rate += samp->dataLength; if (samp->DTS - time_slice>ts) { if (max_rate < rate) max_rate = rate; rate = 0; time_slice = samp->DTS; } gf_isom_sample_del(&samp); } fprintf(stdout, "\nComputed info from media:\n"); scale = 1000; scale /= ts; dur = (u64) (scale * (s64)dur); fprintf(stdout, "\tTotal size %d bytes - Total samples duration %d ms\n", size, (u32) dur); if (!dur) { fprintf(stdout, "\n"); return; } rate = (u32) (size * 8 / (dur/1000)); max_rate *= 8; if (rate >= 1500) { rate /= 1024; max_rate /= 1024; fprintf(stdout, "\tAverage rate %d kbps - Max Rate %d kbps\n", rate, max_rate); } else { fprintf(stdout, "\tAverage rate %d bps - Max Rate %d bps\n", rate, max_rate); } fprintf(stdout, "\n"); count = gf_isom_get_chapter_count(file, trackNum); if (count) { char szDur[20]; const char *name; u64 time; fprintf(stdout, "\nChapters:\n"); for (j=0; j<count; j++) { gf_isom_get_chapter(file, trackNum, j+1, &time, &name); fprintf(stdout, "\tChapter #%d - %s - \"%s\"\n", j+1, format_duration(time, 1000, szDur), name); } }}static const char* ID3v1Genres[] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",}; static const char *id3_get_genre(u32 tag){ if ((tag>0) && (tag <= (sizeof(ID3v1Genres)/sizeof(const char *)) )) { return ID3v1Genres[tag-1]; } return "Unknown";}u32 id3_get_genre_tag(const char *name){ u32 i, count = sizeof(ID3v1Genres)/sizeof(const char *); for (i=0; i<count; i++) { if (!stricmp(ID3v1Genres[i], name)) return i+1; } return 0;}void DumpMovieInfo(GF_ISOFile *file){ GF_InitialObjectDescriptor *iod; u32 i, brand, min, timescale, count, tag_len; const char *tag; u64 create, modif; char szDur[50]; DumpMetaItem(file, 1, 0, "Root Meta"); if (!gf_isom_has_movie(file)) { fprintf(stdout, "File has no movie (moov) - static data container\n"); return; } timescale = gf_isom_get_timescale(file); fprintf(stdout, "* Movie Info *\n\tTimescale %d - Duration %s\n\tFragmented File %s - %d track(s)\n", timescale, format_duration(gf_isom_get_duration(file), timescale, szDur), gf_isom_is_fragmented(file) ? "yes" : "no", gf_isom_get_track_count(file)); if (gf_isom_get_brand_info(file, &brand, &min, NULL) == GF_OK) { fprintf(stdout, "\tFile Brand %s - version %d\n", gf_4cc_to_str(brand), min); } gf_isom_get_creation_time(file, &create, &modif); fprintf(stdout, "\tCreated: %s", format_date(create, szDur)); //fprintf(stdout, "\tModified: %s", format_date(modif, szDur)); fprintf(stdout, "\n"); DumpMetaItem(file, 0, 0, "Moov Meta"); iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(file); if (iod) { if (iod->tag == GF_ODF_IOD_TAG) { fprintf(stdout, "File has root IOD\n"); fprintf(stdout, "Scene PL 0x%02x - Graphics PL 0x%02x - OD PL 0x%02x\n", iod->scene_profileAndLevel, iod->graphics_profileAndLevel, iod->OD_profileAndLevel); fprintf(stdout, "Visual PL: %s (0x%02x)\n", gf_m4v_get_profile_name(iod->visual_profileAndLevel), iod->visual_profileAndLevel); fprintf(stdout, "Audio PL: %s (0x%02x)\n", gf_m4a_get_profile_name(iod->audio_profileAndLevel), iod->audio_profileAndLevel); //fprintf(stdout, "inline profiles included %s\n", iod->inlineProfileFlag ? "yes" : "no"); } else { fprintf(stdout, "File has root OD\n"); } if (!gf_list_count(iod->ESDescriptors)) fprintf(stdout, "No streams included in root OD\n"); gf_odf_desc_del((GF_Descriptor *) iod); } else { fprintf(stdout, "File has no MPEG4 IOD/OD\n"); } if (gf_isom_is_JPEG2000(file)) fprintf(stdout, "File is JPEG 2000\n"); count = gf_isom_get_copyright_count(file); if (count) { const char *lang, *note; fprintf(stdout, "\nCopyrights:\n"); for (i=0; i<count; i++) { gf_isom_get_copyright(file, i+1, &lang, ¬e); fprintf(stdout, "\t(%s) %s\n", lang, note); } } count = gf_isom_get_chapter_count(file, 0); if (count) { char szDur[20]; const char *name; u64 time; fprintf(stdout, "\nChapters:\n"); for (i=0; i<count; i++) { gf_isom_get_chapter(file, 0, i+1, &time, &name); fprintf(stdout, "\tChapter #%d - %s - \"%s\"\n", i+1, format_duration(time, 1000, szDur), name); } } if (gf_isom_apple_get_tag(file, 0, &tag, &tag_len) == GF_OK) { fprintf(stdout, "\niTunes Info:\n"); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tName: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tArtist: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tAlbum: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMMENT, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tComment: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrack: %d / %d\n", tag[3], tag[5]); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPOSER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tComposer: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_WRITER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tWriter: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ALBUM_ARTIST, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tAlbum Artist: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GENRE, &tag, &tag_len)==GF_OK) { if (tag[0]) { fprintf(stdout, "\tGenre: %s\n", tag); } else { fprintf(stdout, "\tGenre: %s\n", id3_get_genre(((u8*)tag)[1])); } } if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COMPILATION, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tCompilation: %s\n", tag[0] ? "Yes" : "No"); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GAPELESS, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tGapeless album: %s\n", tag[0] ? "Yes" : "No"); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_CREATED, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tCreated: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_DISK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tDisk: %d / %d\n", tag[3], tag[5]); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TOOL, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tEncoder Software: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_ENCODER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tEncoded by: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TEMPO, &tag, &tag_len)==GF_OK) { if (tag[0]) { fprintf(stdout, "\tTempo (BPM): %s\n", tag); } else { fprintf(stdout, "\tTempo (BPM): %d\n", tag[1]); } } if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACKNUMBER, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrackNumber: %d / %d\n", tag[3], tag[5]); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_TRACK, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tTrack: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_GROUP, &tag, &tag_len)==GF_OK) fprintf(stdout, "\tGroup: %s\n", tag); if (gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COVER_ART, &tag, &tag_len)==GF_OK) { if (tag_len>>31) fprintf(stdout, "\tCover Art: PNG File\n"); else fprintf(stdout, "\tCover Art: JPEG File\n"); } } fprintf(stdout, "\n"); for (i=0; i<gf_isom_get_track_count(file); i++) { DumpTrackInfo(file, gf_isom_get_track_id(file, i+1), 0); }}typedef struct{ /* when writing to file */ FILE *pes_out; char dump[100]; FILE *pes_out_nhml; char nhml[100]; FILE *pes_out_info; char info[100]; Bool is_info_dumped; /* when dumping TS information */ u32 dump_pid; Bool has_seen_pat;} GF_M2TS_Dump;static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) { u32 i, count; GF_M2TS_Program *prog; GF_M2TS_PES_PCK *pck; GF_M2TS_Dump *dumper = (GF_M2TS_Dump *)ts->user; switch (evt_type) { case GF_M2TS_EVT_PAT_FOUND: fprintf(stdout, "Initial PAT found - %d programs\n", gf_list_count(ts->programs) ); break; case GF_M2TS_EVT_PAT_UPDATE: fprintf(stdout, "PAT updated - %d programs\n", gf_list_count(ts->programs) ); break; case GF_M2TS_EVT_PAT_REPEAT: dumper->has_seen_pat = 1;// fprintf(stdout, "Repeated PAT found - %d programs\n", gf_list_count(ts->programs) ); break; case GF_M2TS_EVT_PMT_FOUND: prog = (GF_M2TS_Program*)par; count = gf_list_count(prog->streams); fprintf(stdout, "Program number %d found - %d streams:\n", prog->number, count); for (i=0; i<count; i++) { GF_M2TS_ES *es = gf_list_get(prog->streams, i); if (es->pid == prog->pmt_pid) fprintf(stdout, "\tPID %d: Program Map Table\n", es->pid); else { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; fprintf(stdout, "\tPID %d: %s ", pes->pid, gf_m2ts_get_stream_name(pes->stream_type) ); if (pes->mpeg4_es_id) fprintf(stdout, " - MPEG-4 ES ID %d", pes->mpeg4_es_id); fprintf(stdout, "\n"); } } break; case GF_M2TS_EVT_PMT_UPDATE: fprintf(stdout, "Program list updated - %d streams\n", gf_list_count( ((GF_M2TS_Program*)par)->streams) ); break; case GF_M2TS_EVT_PMT_REPEAT:// fprintf(stdout, "Repeated Program list found - %d streams\n", gf_list_count( ((GF_M2TS_Program*)par)->streams) ); break; case GF_M2TS_EVT_SDT_FOUND: count = gf_list_count(ts->SDTs) ; fprintf(stdout, "Program Description found - %d desc:\n", count); for (i=0; i<count; i++) { GF_M2TS_SDT *sdt = gf_list_get(ts->SDTs, i); fprintf(stdout, "\tServiceID %d - Provider %s - Name %s\n", sdt->service_id, sdt->provider, sdt->service); } break; case GF_M2TS_EVT_SDT_UPDATE: count = gf_list_count(ts->SDTs) ; fprintf(stdout, "Program Description updated - %d desc\n", count); for (i=0; i<count; i++) { GF_M2TS_SDT *sdt = gf_list_get(ts->SDTs, i); fprintf(stdout, "\tServiceID %d - Provider %s - Name %s\n", sdt->service_id, sdt->provider, sdt->service); } break; case GF_M2TS_EVT_SDT_REPEAT:// fprintf(stdout, "Repeated Program Description - %d desc\n", gf_list_count(ts->SDTs) ); break; case GF_M2TS_EVT_PES_PCK: pck = par; //fprintf(stdout, "PES(%d): DTS "LLD" PTS" LLD" RAP %d size %d\n", pck->stream->pid, pck->DTS, pck->PTS, pck->rap, pck->data_len); if (dumper->pes_out && (dumper->dump_pid == pck->stream->pid)) { fwrite(pck->data, pck->data_len, 1, dumper->pes_out); } break; case GF_M2TS_EVT_SL_PCK:#if 0 { GF_M2TS_SL_PCK *sl_pck = par; if (dumper->pes_out && (dumper->dump_pid == sl_pck->stream->pid)) { GF_SLHeader header; u32 header_len; if (sl_pck->stream->mpeg4_es_id) { GF_ESD *esd = ((GF_M2TS_PES*)sl_pck->stream)->esd; if (!dumper->is_info_dumped) { if (esd->decoderConfig->decoderSpecificInfo) fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, dumper->pes_out_info); dumper->is_info_dumped = 1; fprintf(dumper->pes_out_nhml, "<NHNTStream version=\"1.0\" "); fprintf(dumper->pes_out_nhml, "timeScale=\"%d\" ", esd->slConfig->timestampResolution); fprintf(dumper->pes_out_nhml, "streamType=\"%d\" ", esd->decoderConfig->streamType); fprintf(dumper->pes_out_nhml, "objectTypeIndication=\"%d\" ", esd->decoderConfig->objectTypeIndication); if (esd->decoderConfig->decoderSpecificInfo) fprintf(dumper->pes_out_nhml, "specificInfoFile=\"%s\" ", dumper->info); fprintf(dumper->pes_out_nhml, "baseMediaFile=\"%s\" ", dumper->dump); fprintf(dumper->pes_out_nhml, "inRootOD=\"yes\">\n"); } gf_sl_depacketize(esd->slConfig, &header, sl_pck->data, sl_pck->data_len, &header_len); fwrite(sl_pck->data+header_len, sl_pck->data_len-header_len, 1, dumper->pes_out); fprintf(dumper->pes_out_nhml, "<NHNTSample DTS=\""LLD"\" dataLength=\"%d\" isRAP=\"%s\"/>\n", LLD_CAST header.decodingTimeStamp, sl_pck->data_len-header_len, (header.randomAccessPointFlag?"yes":"no")); } } }#endif break; }}void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name){ char data[188]; GF_M2TS_Dump dumper; u32 size, fsize, fdone; GF_M2TS_Demuxer *ts; FILE *src = fopen(mpeg2ts_file, "rb"); ts = gf_m2ts_demux_new(); ts->on_event = on_m2ts_dump_event; memset(&dumper, 0, sizeof(GF_M2TS_Dump)); ts->user = &dumper; fseek(src, 0, SEEK_END); fsize = ftell(src); fseek(src, 0, SEEK_SET); fdone = 0; if (pes_out_name) { char *pid = strrchr(pes_out_name, '#'); if (pid) { dumper.dump_pid = atoi(pid+1); pid[0] = 0; sprintf(dumper.dump, "%s_%d.media", pes_out_name, dumper.dump_pid); dumper.pes_out = fopen(dumper.dump, "wb"); sprintf(dumper.nhml, "%s_%d.nhml", pes_out_name, dumper.dump_pid); dumper.pes_out_nhml = fopen(dumper.nhml, "wt"); sprintf(dumper.info, "%s_%d.info", pes_out_name, dumper.dump_pid); dumper.pes_out_info = fopen(dumper.info, "wb"); pid[0] = '#'; } } while (!feof(src)) { size = fread(data, 1, 188, src); if (size<188) break; gf_m2ts_process_data(ts, data, size); if (dumper.has_seen_pat) break; } gf_m2ts_reset_parsers(ts); gf_f64_seek(src, 0, SEEK_SET); fdone = 0; while (!feof(src)) { size = fread(data, 1, 188, src); if (size<188) break; gf_m2ts_process_data(ts, data, size); fdone += size; gf_set_progress("MPEG-2 TS Parsing", fdone, fsize); } fclose(src); gf_m2ts_demux_del(ts); if (dumper.pes_out) fclose(dumper.pes_out); if (dumper.pes_out_nhml) { if (dumper.is_info_dumped) fprintf(dumper.pes_out_nhml, "</NHNTStream>\n"); fclose(dumper.pes_out_nhml); fclose(dumper.pes_out_info); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -