bool CMpeg3AudioByteStream::start_next_frame (uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *pts, void **ud) { uint64_t ts; uint32_t freq_ts; if (m_eof) { return false; } m_eof = mpeg2ps_get_audio_frame(m_file, m_stream, buffer, buflen, TS_MSEC, &freq_ts, &ts) == false; if (m_eof) return false; #ifdef OUTPUT_TO_FILE fwrite(*buffer, buflen, 1, m_output_file); #endif pts->audio_freq_timestamp = freq_ts; pts->audio_freq = m_freq; pts->msec_timestamp = ts; pts->timestamp_is_pts = false; #ifdef DEBUG_MPEG_FRAME mpeg3f_message(LOG_DEBUG, "audiostart %u %u "U64, *buflen, freq_ts, ts); #endif return true; }
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; }