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;
}
Example #3
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;
}
Example #4
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;
}