int create_media_for_mpeg_file (CPlayerSession *psptr, const char *name, int have_audio_driver, control_callback_vft_t *cc_vft) { mpeg2ps_t *file; int video_streams, audio_streams; int video_cnt, audio_cnt; int ix; codec_plugin_t *plugin; int video_offset, audio_offset; int ret; int sdesc; file = mpeg2ps_init(name); if (file == NULL) { psptr->set_message("file %s is not a valid .mpg file", name); return -1; } psptr->set_media_close_callback(close_mpeg3_file, (void *)file); video_streams = mpeg2ps_get_video_stream_count(file); audio_streams = mpeg2ps_get_audio_stream_count(file); video_cnt = 0; if (video_streams > 0) { plugin = check_for_video_codec(STREAM_TYPE_MPEG_FILE, "mp2v", NULL, mpeg2ps_get_video_stream_type(file, 0), -1, NULL, 0, &config); if (plugin != NULL) video_cnt = video_streams; } for (ix = 0, audio_cnt = 0; ix < audio_streams; ix++) { plugin = check_for_audio_codec(STREAM_TYPE_MPEG_FILE, NULL, NULL, mpeg2ps_get_audio_stream_type(file, ix), -1, NULL, 0, &config); if (plugin != NULL) audio_cnt++; } video_query_t *vq; audio_query_t *aq; if (video_cnt > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_cnt); } else { vq = NULL; } if (have_audio_driver && audio_cnt > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_cnt); } else { aq = NULL; } video_offset = 0; for (ix = 0; ix < video_cnt; ix++) { vq[video_offset].track_id = ix; vq[video_offset].stream_type = STREAM_TYPE_MPEG_FILE; vq[video_offset].compressor = "mp2v"; vq[video_offset].type = mpeg2ps_get_video_stream_type(file, ix); vq[video_offset].profile = -1; vq[video_offset].fptr = NULL; vq[video_offset].h = mpeg2ps_get_video_stream_height(file, ix); vq[video_offset].w = mpeg2ps_get_video_stream_width(file, ix); vq[video_offset].frame_rate = mpeg2ps_get_video_stream_framerate(file, ix); vq[video_offset].config = NULL; vq[video_offset].config_len = 0; vq[video_offset].enabled = 0; vq[video_offset].reference = NULL; video_offset++; } audio_offset = 0; if (have_audio_driver) { for (ix = 0; ix < audio_streams; ix++) { plugin = check_for_audio_codec(STREAM_TYPE_MPEG_FILE, NULL, NULL, mpeg2ps_get_audio_stream_type(file, ix), -1, NULL, 0, &config); if (plugin != NULL) { aq[audio_offset].track_id = ix; aq[audio_offset].stream_type = STREAM_TYPE_MPEG_FILE; aq[audio_offset].compressor = NULL; aq[audio_offset].type = mpeg2ps_get_audio_stream_type(file, ix); aq[audio_offset].profile = -1; aq[audio_offset].fptr = NULL; aq[audio_offset].config = NULL; aq[audio_offset].config_len = 0; aq[audio_offset].sampling_freq = mpeg2ps_get_audio_stream_sample_freq(file, ix); aq[audio_offset].chans = mpeg2ps_get_audio_stream_channels(file, ix); aq[audio_offset].enabled = 0; aq[audio_offset].reference = NULL; audio_offset++; } else { mpeg3f_message(LOG_ERR, "Unsupported audio type %s in track %d", mpeg2ps_get_audio_stream_name(file, ix), ix); } } } if (audio_offset == 0 && video_offset == 0) { psptr->set_message("No playable streams in file"); CHECK_AND_FREE(aq); CHECK_AND_FREE(vq); return -1; } if (cc_vft && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq, 0, NULL); } else { if (video_offset > 0) vq[0].enabled = 1; if (audio_offset > 0) aq[0].enabled = 1; } ret = 0; sdesc = 1; for (ix = 0; ret >= 0 && ix < video_offset; ix++) { if (vq[ix].enabled) { ret = create_mpeg3_video(&vq[ix], file, psptr, sdesc); if (ret <= 0) { } } } if (ret >= 0) { for (ix = 0; ix < audio_offset && ret >= 0; ix++) { if (aq[ix].enabled) { ret = create_mpeg3_audio(&aq[ix], file, psptr, sdesc); if (ret <= 0) { } } } } free(vq); free(aq); if (ret < 0) { mpeg2ps_close(file); return ret; } psptr->session_set_seekable(1); return 0; }
int main(int argc, char** argv) { char* usageString = "[--video] [--audio] <file-name>\n"; bool dump_audio = false, dump_video = false; uint audio_stream = 0, video_stream = 0; char *infilename; char outfilename[FILENAME_MAX], *suffix; size_t suffix_len; FILE *outfile; mpeg2ps_t *infile; /* begin processing command line */ char* progName = argv[0]; long cnt = 0; bool dump = false; while (1) { int c = -1; int option_index = 0; static struct option long_options[] = { { "audio", 2, 0, 'a' }, { "video", 2, 0, 'v' }, { "dump", 0, 0, 'd' }, { "version", 0, 0, 'V' }, { NULL, 0, 0, 0 } }; c = getopt_long_only(argc, argv, "a:v:Vd", long_options, &option_index); if (c == -1) break; switch (c) { case 'v': dump_video = true; if (optarg) { uint32_t readstream; if (sscanf(optarg, "%u", &readstream) == 1) { video_stream = readstream; } } break; case 'a': dump_audio = true; if (optarg) { uint32_t readstream; if (sscanf(optarg, "%u", &readstream) == 1) { audio_stream = readstream; } } break; case 'd': dump = true; break; 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); } } if ((argc - optind) < 1) { fprintf(stderr, "usage: %s %s\n", progName, usageString); exit(1); } #if 0 if (dump_audio == 0 && dump_video == 0) { dump_audio = dump_video = 1; } #endif while (optind < argc) { infilename = argv[optind]; optind++; suffix = strrchr(infilename, '.'); suffix_len = suffix - infilename; if (suffix == NULL) { fprintf(stderr, "can't find suffix in %s\n", infilename); continue; } infile = mpeg2ps_init(infilename); if (infile == NULL) { fprintf(stderr, "%s is not a valid mpeg file\n", infilename); continue; } uint8_t *buf = NULL; uint32_t len = 0; uint64_t ftime; uint32_t freq_ftime; uint32_t last_freq_time = 0; if (dump_audio) { if (mpeg2ps_get_audio_stream_count(infile) == 0) { fprintf(stderr, "no audio streams in %s\n", infilename); } else if (audio_stream >= mpeg2ps_get_audio_stream_count(infile)) { fprintf(stderr, "audio stream %d does not exist\n", audio_stream); } else { char *slash; slash = strrchr(infilename, '/'); if (slash != NULL) { slash++; suffix_len = suffix - slash; memcpy(outfilename, slash, suffix_len); } else { memcpy(outfilename, infilename, suffix_len); } mpeg2ps_audio_type_t audio_type = mpeg2ps_get_audio_stream_type(infile, audio_stream); switch (audio_type) { case MPEG_AUDIO_MPEG: strcpy(outfilename + suffix_len, ".mp3"); break; case MPEG_AUDIO_AC3: strcpy(outfilename + suffix_len, ".ac3"); break; case MPEG_AUDIO_LPCM: strcpy(outfilename + suffix_len, ".pcm"); break; default: break; } outfile = fopen(outfilename, FOPEN_WRITE_BINARY); while (mpeg2ps_get_audio_frame(infile, audio_stream, &buf, &len, TS_MSEC, &freq_ftime, &ftime)) { printf("audio len %d time %u "U64"\n", len, freq_ftime, ftime); if (audio_type == MPEG_AUDIO_LPCM) { if (last_freq_time != 0) { if (last_freq_time != freq_ftime) { printf("error in timestamp %u %u\n", freq_ftime, last_freq_time); } } last_freq_time = freq_ftime + (len / 4); #if 0 if (last_freq_time + 1152 != freq_ftime) { printf("error in timestamp %d\n", freq_ftime - last_freq_time); } last_freq_time = freq_ftime; #endif } fwrite(buf, len, 1, outfile); cnt++; } fclose(outfile); printf("%ld audio frames\n", cnt); } } if (dump_video) { if (mpeg2ps_get_video_stream_count(infile) == 0) { fprintf(stderr, "no video streams in %s\n", infilename); } else if (video_stream >= mpeg2ps_get_video_stream_count(infile)) { fprintf(stderr, "video stream %d does not exist\n", video_stream); } else { char *slash; slash = strrchr(infilename, '/'); if (slash != NULL) { slash++; suffix_len = suffix - slash; memcpy(outfilename, slash, suffix_len); } else { memcpy(outfilename, infilename, suffix_len); } mpeg2ps_video_type_t video_type = mpeg2ps_get_video_stream_type(infile, video_stream); switch (video_type) { case MPEG_VIDEO_H264: strcpy(outfilename + suffix_len, ".264"); break; default: strcpy(outfilename + suffix_len, ".m2v"); } outfile = fopen(outfilename, FOPEN_WRITE_BINARY); cnt = 0; while (mpeg2ps_get_video_frame(infile, video_stream, &buf, &len, NULL, TS_MSEC, &ftime)) { printf("video len %d time "U64"\n", len, ftime); if (buf[len - 2] == 1 && buf[len - 3] == 0 && buf[len - 4] == 0) len -= 4; fwrite(buf, len, 1, outfile); cnt++; } fclose(outfile); printf("%ld video frames\n", cnt); } } mpeg2ps_close(infile); } return 0; }
static MP4TrackId AudioCreate (MP4FileHandle mp4file, mpeg2ps_t *file, int astream, bool doEncrypt) { uint16_t freq; int type; MP4TrackId id; uint16_t samples_per_frame; uint8_t *buf = NULL; uint32_t blen = 0; uint32_t frame_num = 1; ismacryp_session_id_t ismaCrypSId; mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); MP4AV_Mp3Header hdr; u_int8_t mpegVersion; memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); type = mpeg2ps_get_audio_stream_type(file, astream); if (type != MPEG_AUDIO_MPEG) { fprintf(stderr, "Unsupported audio format %d in audio stream %d\n", type, astream); return MP4_INVALID_TRACK_ID; } freq = mpeg2ps_get_audio_stream_sample_freq(file, astream); if (mpeg2ps_get_audio_frame(file, astream, &buf, &blen, TS_90000, NULL, NULL) == false) { fprintf(stderr, "No audio tracks in audio stream %d\n", astream); return MP4_INVALID_TRACK_ID; } hdr = MP4AV_Mp3HeaderFromBytes(buf); mpegVersion = MP4AV_Mp3GetHdrVersion(hdr); samples_per_frame = MP4AV_Mp3GetHdrSamplingWindow(hdr); u_int8_t audioType = MP4AV_Mp3ToMp4AudioType(mpegVersion); if (audioType == MP4_INVALID_AUDIO_TYPE || samples_per_frame == 0) { fprintf(stderr, "%s: data in file doesn't appear to be valid audio\n", ProgName); return MP4_INVALID_TRACK_ID; } MP4Duration duration = (90000 * samples_per_frame) / freq; if (doEncrypt) { // initialize the ismacryp session if (ismacrypInitSession(&ismaCrypSId,KeyTypeAudio) != 0) { fprintf(stderr, "%s: could not initialize the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n", ProgName, ismaCrypSId); if (icPp->kms_uri != NULL) free(icPp->kms_uri); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) { fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } id = MP4AddEncAudioTrack(mp4file, 90000, duration, icPp, audioType); } else { id = MP4AddAudioTrack(mp4file, 90000, duration, audioType); } if (id == MP4_INVALID_TRACK_ID) { fprintf(stderr, "%s: can't create audio track from stream %d\n", ProgName, astream); return MP4_INVALID_TRACK_ID; } if (MP4GetNumberOfTracks(mp4file, MP4_AUDIO_TRACK_TYPE) == 1) { MP4SetAudioProfileLevel(mp4file, 0xFE); } do { // encrypt if needed if (doEncrypt) { u_int8_t* encSampleData = NULL; u_int32_t encSampleLen = 0; if (ismacrypEncryptSampleAddHeader(ismaCrypSId, blen, buf, &encSampleLen, &encSampleData) != 0) { fprintf(stderr, "%s: can't encrypt audio sample and add header %u\n", ProgName, id); } // now write the sample if (!MP4WriteSample(mp4file, id, encSampleData, encSampleLen)) { fprintf(stderr, "%s: can't write audio track %u, stream %d", ProgName, frame_num, astream); MP4DeleteTrack(mp4file, id); return MP4_INVALID_TRACK_ID; } if (encSampleData != NULL) { free(encSampleData); } } // now write the sample if (!MP4WriteSample(mp4file, id, buf, blen)) { fprintf(stderr, "%s: can't write audio track %u, stream %d", ProgName, frame_num, astream); MP4DeleteTrack(mp4file, id); return MP4_INVALID_TRACK_ID; } frame_num++; #if 0 if ((frame_num % 100) == 0) printf("Audio frame %d\n", frame_num); #endif } while (mpeg2ps_get_audio_frame(file, astream, &buf, &blen, TS_90000, NULL, NULL)); // if encrypting, terminate the ismacryp session if (doEncrypt) { if (ismacrypEndSession(ismaCrypSId) != 0) { fprintf(stderr, "%s: could not end the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } } return id; }