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 VideoCreate (MP4FileHandle mp4file, mpeg2ps_t *file, int vstream, bool doEncrypt) { double frame_rate = mpeg2ps_get_video_stream_framerate(file, vstream); uint8_t video_type; uint16_t w, h; MP4TrackId id; ismacryp_session_id_t ismaCrypSId; mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); #ifdef _WIN32 MP4Duration mp4FrameDuration; mp4FrameDuration = (MP4Duration)((double)Mp4TimeScale / frame_rate); #else MP4Duration mp4FrameDuration = (MP4Duration)(Mp4TimeScale / frame_rate); #endif h = mpeg2ps_get_video_stream_height(file, vstream); w = mpeg2ps_get_video_stream_width(file, vstream); video_type = mpeg2ps_get_video_stream_type(file, vstream) == MPEG_VIDEO_MPEG2 ? MP4_MPEG2_MAIN_VIDEO_TYPE : MP4_MPEG1_VIDEO_TYPE; if (doEncrypt) { // initialize session if (ismacrypInitSession(&ismaCrypSId,KeyTypeVideo) != 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 = MP4AddEncVideoTrack(mp4file, Mp4TimeScale, mp4FrameDuration, w, h, icPp, video_type); } else { id = MP4AddVideoTrack(mp4file, Mp4TimeScale, mp4FrameDuration, w, h, video_type); } //printf("duration "U64" w %d h %d type %x\n", mp4FrameDuration, w, h, video_type); if (MP4GetNumberOfTracks(mp4file, MP4_VIDEO_TRACK_TYPE) == 1) { MP4SetVideoProfileLevel(mp4file, 0xfe); // undefined profile } if (id == MP4_INVALID_TRACK_ID) { fprintf(stderr, "%s:Couldn't add video track %d", ProgName, vstream); return MP4_INVALID_TRACK_ID; } uint8_t *buf; uint32_t blen; uint32_t frames = 1; #if 0 printf("Processing %lu video frames\n", frames_max); #endif uint32_t refFrame = 1; uint8_t frame_type; while (mpeg2ps_get_video_frame(file, vstream, &buf, &blen, &frame_type, TS_90000, NULL)) { if (buf[blen - 4] == 0 && buf[blen - 3] == 0 && buf[blen - 2] == 1) blen -= 4; // encrypt the sample if neeed 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 video sample and add header %u\n", ProgName, id); } MP4WriteSample(mp4file, id, encSampleData, encSampleLen, mp4FrameDuration, 0, frame_type == 1 ? true : false); if (encSampleData != NULL) { free(encSampleData); } } else { MP4WriteSample(mp4file, id, buf, blen, mp4FrameDuration, 0, frame_type == 1 ? true : false); #if 0 printf("frame %d len %d duration "U64" ftype %d\n", frames, blen, mp4FrameDuration, frame_type); #endif } if (frame_type != 3) { // I or P frame MP4SetSampleRenderingOffset(mp4file, id, refFrame, (frames - refFrame) * mp4FrameDuration); refFrame = frames; } frames++; #if 0 if ((frames % 100) == 0) printf("%d frames\n", frames); #endif } // 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; }