bool CMpeg3VideoByteStream::skip_next_frame (frame_timestamp_t *pts, int *pSync, uint8_t **buffer, uint32_t *buflen, void **ud) { uint8_t ftype; ftype = 0; m_eof = mpeg2ps_get_video_frame(m_file, m_stream, buffer, buflen, &ftype, TS_MSEC, &pts->msec_timestamp) == false; if (m_eof) return true; *pSync = ftype == 1 ? 1 : 0; return true; }
bool CMpeg3VideoByteStream::start_next_frame (uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *pts, void **ud) { m_eof = mpeg2ps_get_video_frame(m_file, m_stream, buffer, buflen, NULL, TS_MSEC, &pts->msec_timestamp) == false; if (m_eof) { return false; } pts->timestamp_is_pts = false; #ifdef DEBUG_MPEG_FRAME mpeg3f_message(LOG_DEBUG, "start next frame %d "U64, *buflen, pts->msec_timestamp); #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 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; }