static void print_track_info (mp4dmuxflt_prc_t * ap_prc, const MP4TrackId tid) { assert (ap_prc); assert (ap_prc->mp4v2_hdl_ != MP4_INVALID_FILE_HANDLE); if (MP4_INVALID_TRACK_ID != tid) { char * p_track_nfo = MP4Info (ap_prc->mp4v2_hdl_, tid); TIZ_DEBUG (handleOf (ap_prc), "track info: ", (p_track_nfo ? p_track_nfo : "")); tiz_mem_free (p_track_nfo); } }
extern "C" char* MP4FileInfo( const char* fileName, MP4TrackId trackId) { MP4FileHandle mp4File = MP4Read(fileName); if (!mp4File) { return NULL; } char* info = MP4Info(mp4File, trackId); MP4Close(mp4File); return info; // caller should free this }
int CMp4File::create_text(CPlayerSession *psptr, text_query_t *tq, uint text_offset, uint &start_desc) { uint ix; //uint64_t IVLength; CPlayerMedia *mptr; codec_plugin_t *plugin; uint32_t verb = MP4GetVerbosity(m_mp4file); for (ix = 0; ix < text_offset; ix++) { if (tq[ix].enabled != 0) { CMp4TextByteStream *tbyte; mptr = new CPlayerMedia(psptr, TIMED_TEXT_SYNC); if (mptr == NULL) { return (-1); } /* check if ismacryp */ #if 0 uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (MP4IsIsmaCrypMediaTrack(m_mp4file, aq[ix].track_id)) { IVLength = MP4GetTrackIntegerProperty(m_mp4file, aq[ix].track_id, "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.IV-length"); abyte = new CMp4EncAudioByteStream(this, aq[ix].track_id, IVLength); } else { abyte = new CMp4AudioByteStream(this, aq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); #else tbyte = new CMp4TextByteStream(this, tq[ix].track_id); #endif int ret; plugin = check_for_text_codec(tq[ix].stream_type, tq[ix].compressor, NULL, NULL, 0, &config); ret = mptr->create_text_plugin(plugin, STREAM_TYPE_MP4_FILE, tq[ix].compressor, NULL, // sdp info NULL, 0); if (ret < 0) { mp4f_message(LOG_ERR, "Couldn't create text from plugin %s", plugin->c_name); psptr->set_message("Couldn't start text plugin %s", plugin->c_name); delete mptr; delete tbyte; return -1; } ret = mptr->create_media("text", tbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, tq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { CHECK_AND_FREE(tq[ix].config); } } return 0; }
int CMp4File::create_audio(CPlayerSession *psptr, audio_query_t *aq, uint audio_offset, uint &start_desc) { uint ix; uint64_t IVLength; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < audio_offset; ix++) { if (aq[ix].enabled != 0) { CMp4AudioByteStream *abyte; mptr = new CPlayerMedia(psptr, AUDIO_SYNC); if (mptr == NULL) { return (-1); } /* check if ismacryp */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (MP4IsIsmaCrypMediaTrack(m_mp4file, aq[ix].track_id)) { MP4GetTrackIntegerProperty(m_mp4file, aq[ix].track_id, "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.IV-length", &IVLength); abyte = new CMp4EncAudioByteStream(this, aq[ix].track_id, IVLength); } else { abyte = new CMp4AudioByteStream(this, aq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); audio_info_t *ainfo; ainfo = (audio_info_t *)malloc(sizeof(audio_info_t)); memset(ainfo, 0, sizeof(*ainfo)); ainfo->freq = aq[ix].sampling_freq; if (aq[ix].chans != -1) { ainfo->chans = aq[ix].chans; } if ((aq[ix].type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) || (aq[ix].type == MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE)) { ainfo->bitspersample = 16; } int ret; plugin = check_for_audio_codec(STREAM_TYPE_MP4_FILE, aq[ix].compressor, // media_data field NULL, aq[ix].type, aq[ix].profile, aq[ix].config, aq[ix].config_len, &config); ret = mptr->create_audio_plugin(plugin, STREAM_TYPE_MP4_FILE, aq[ix].compressor, aq[ix].type, aq[ix].profile, NULL, // sdp info ainfo, // audio info aq[ix].config, aq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Couldn't create audio from plugin %s", plugin->c_name); psptr->set_message("Couldn't start audio plugin %s", plugin->c_name); delete mptr; delete abyte; return -1; } ret = mptr->create_media("audio", abyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, aq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (aq[ix].config != NULL) free((void *)aq[ix].config); } } return 0; }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte; uint64_t IVLength; /* check if ismacryp */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].compressor, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].compressor, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } return 0; }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; const char *file_kms_uri; const char *inuse_kms_uri; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte = NULL; uint64_t IVLength; /* check if clear-text or ismacryp. * in this context original format is encv * and compressor specifies which codec */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].original_fmt, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].original_fmt, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); if (strcasecmp(vq[ix].compressor, "mp4v") == 0) { vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else if (((strcasecmp(vq[ix].compressor, "avc1") == 0) || (strcasecmp(vq[ix].compressor, "264b")) == 0)) { vbyte = new CMp4EncH264VideoByteStream(this, vq[ix].track_id,IVLength); // check if file kms uri matches in-use kms uri // advisory only MP4GetTrackStringProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI", &file_kms_uri); inuse_kms_uri = ((CMp4EncH264VideoByteStream *)vbyte)->get_inuse_kms_uri(); if (file_kms_uri && inuse_kms_uri) { if (strcmp(file_kms_uri, inuse_kms_uri)) { mp4f_message(LOG_DEBUG, "KMS in file (%s) does not match KMS in use (%s)\n", file_kms_uri, inuse_kms_uri); } } } } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } return 0; }
int main(int argc, char** argv) { const char* usageString = "[-l] [-t <track-id>] [-s <sample-id>] [-v [<level>]] <file-name>\n"; bool doList = false; bool doSamples = false; MP4TrackId trackId = MP4_INVALID_TRACK_ID; MP4SampleId sampleId = MP4_INVALID_SAMPLE_ID; char* dstFileName = NULL; u_int32_t verbosity = MP4_DETAILS_ERROR; fprintf(stderr, "You don't want to use this utility - use mp4creator --extract instead\n"); fprintf(stderr, "If you really want to use it, remove this warning and the exit call\n"); fprintf(stderr, "from the source file\n"); exit(-1); /* begin processing command line */ ProgName = argv[0]; while (true) { int c = -1; int option_index = 0; static struct option long_options[] = { { "list", 0, 0, 'l' }, { "track", 1, 0, 't' }, { "sample", 2, 0, 's' }, { "verbose", 2, 0, 'v' }, { "version", 0, 0, 'V' }, { NULL, 0, 0, 0 } }; c = getopt_long_only(argc, argv, "lt:s::v::V", long_options, &option_index); if (c == -1) break; switch (c) { case 'l': doList = true; break; case 's': doSamples = true; if (optarg) { if (sscanf(optarg, "%u", &sampleId) != 1) { fprintf(stderr, "%s: bad sample-id specified: %s\n", ProgName, optarg); } } break; case 't': if (sscanf(optarg, "%u", &trackId) != 1) { fprintf(stderr, "%s: bad track-id specified: %s\n", ProgName, optarg); exit(1); } break; case 'v': verbosity |= MP4_DETAILS_READ; if (optarg) { u_int32_t level; if (sscanf(optarg, "%u", &level) == 1) { if (level >= 2) { verbosity |= MP4_DETAILS_TABLE; } if (level >= 3) { verbosity |= MP4_DETAILS_SAMPLE; } if (level >= 4) { verbosity = MP4_DETAILS_ALL; } } } break; case '?': fprintf(stderr, "usage: %s %s", ProgName, usageString); exit(0); case 'V': fprintf(stderr, "%s - %s version %s\n", ProgName, MPEG4IP_PACKAGE, MPEG4IP_VERSION); exit(0); default: fprintf(stderr, "%s: unknown option specified, ignoring: %c\n", ProgName, c); } } /* check that we have at least one non-option argument */ if ((argc - optind) < 1) { fprintf(stderr, "usage: %s %s", ProgName, usageString); exit(1); } if (verbosity) { fprintf(stderr, "%s version %s\n", ProgName, MPEG4IP_VERSION); } /* point to the specified file names */ Mp4PathName = argv[optind++]; /* get dest file name for a single track */ if (trackId && (argc - optind) > 0) { dstFileName = argv[optind++]; } char* lastSlash = strrchr(Mp4PathName, '/'); if (lastSlash) { Mp4FileName = lastSlash + 1; } else { Mp4FileName = Mp4PathName; } /* warn about extraneous non-option arguments */ if (optind < argc) { fprintf(stderr, "%s: unknown options specified, ignoring: ", ProgName); while (optind < argc) { fprintf(stderr, "%s ", argv[optind++]); } fprintf(stderr, "\n"); } /* end processing of command line */ MP4FileHandle mp4File = MP4Read(Mp4PathName, verbosity); if (!mp4File) { exit(1); } if (doList) { MP4Info(mp4File); exit(0); } if (trackId == 0) { u_int32_t numTracks = MP4GetNumberOfTracks(mp4File); for (u_int32_t i = 0; i < numTracks; i++) { trackId = MP4FindTrackId(mp4File, i); ExtractTrack(mp4File, trackId, doSamples, sampleId); } } else { ExtractTrack(mp4File, trackId, doSamples, sampleId, dstFileName); } MP4Close(mp4File); return(0); }