Esempio n. 1
0
VALUE _mp4v2_video_init(MP4FileHandle mp4v2, MP4TrackId track_id) {
  VALUE video = rb_class_new_instance(0, NULL, rb_cVideo);

  video = _mp4v2_track_init(video, mp4v2, track_id);

  uint16_t height = MP4GetTrackVideoHeight(mp4v2, track_id);
  uint16_t width = MP4GetTrackVideoWidth(mp4v2, track_id);
  rb_ivar_set(video, rb_intern("@height"), INT2FIX(height));
  rb_ivar_set(video, rb_intern("@width"), INT2FIX(width));

  rb_ivar_set(video, rb_intern("@fps"), DBL2NUM(MP4GetTrackVideoFrameRate(mp4v2, track_id)));

  return video;
}
Esempio n. 2
0
int CMp4File::create_media (CPlayerSession *psptr,
			    int have_audio_driver,
			    control_callback_vft_t *cc_vft)
{
  uint video_count, video_offset;
  uint text_count, text_offset;
  uint audio_count, audio_offset;
  MP4TrackId trackId;
  video_query_t *vq;
  audio_query_t *aq;
  text_query_t *tq;
  uint ix;
  codec_plugin_t *plugin;
  int ret_value = 0;
  uint8_t *foo;
  u_int32_t bufsize;
  
  uint32_t verb = MP4GetVerbosity(m_mp4file);
  MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR));
  video_count = MP4GetNumberOfTracks(m_mp4file, MP4_VIDEO_TRACK_TYPE);
  audio_count = MP4GetNumberOfTracks(m_mp4file, MP4_AUDIO_TRACK_TYPE);
  text_count = MP4GetNumberOfTracks(m_mp4file, MP4_CNTL_TRACK_TYPE);
  mp4f_message(LOG_DEBUG, "cntl tracks %u", text_count);
  MP4SetVerbosity(m_mp4file, verb);

  if (video_count == 0 && audio_count == 0 && text_count == 0) {
    psptr->set_message("No audio, video or control tracks in file");
    return -1;
  }

  if (video_count > 0) {
    vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count);
    memset(vq, 0, sizeof(video_query_t) * video_count);
  } else {
    vq = NULL;
  }
  if (have_audio_driver && audio_count > 0) {
    aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count);
    memset(aq, 0, sizeof(audio_query_t) * audio_count);
  } else {
    aq = NULL;
  }

  if (text_count > 0) {
    tq = (text_query_t *)malloc(sizeof(text_query_t) * text_count);
    memset(tq, 0, sizeof(text_query_t) * text_count);
  } else {
    tq = NULL;
  }
  for (ix = 0, video_offset = 0; ix < video_count; ix++) {
    trackId = MP4FindTrackId(m_mp4file, ix, MP4_VIDEO_TRACK_TYPE);
    const char *media_data_name;
    media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId);
    // for now, treat mp4v and encv the same
    vq[video_offset].track_id = trackId;
    vq[video_offset].stream_type = STREAM_TYPE_MP4_FILE;
    vq[video_offset].compressor = media_data_name;
    if (strcasecmp(media_data_name, "mp4v") == 0 ||
	strcasecmp(media_data_name, "encv") == 0) {
      uint8_t video_type = MP4GetTrackEsdsObjectTypeId(m_mp4file, trackId);
      uint8_t profileID = MP4GetVideoProfileLevel(m_mp4file, trackId);
      mp4f_message(LOG_DEBUG, "MP4 - got track %x profile ID %d", 
		 trackId, profileID);
      MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR));
      MP4GetTrackESConfiguration(m_mp4file, trackId, &foo, &bufsize);
      MP4SetVerbosity(m_mp4file, verb);
      vq[video_offset].type = video_type;
      vq[video_offset].profile = profileID;
      vq[video_offset].fptr = NULL;
      vq[video_offset].config = foo;
      vq[video_offset].config_len = bufsize;
    } else if (strcasecmp(media_data_name, "avc1") == 0) {
      uint8_t profile, level;
      uint8_t **seqheader, **pictheader;
      uint32_t *pictheadersize, *seqheadersize;
      uint32_t ix;
      MP4GetTrackH264ProfileLevel(m_mp4file, trackId, &profile, &level);
      MP4GetTrackH264SeqPictHeaders(m_mp4file, trackId, 
				    &seqheader, &seqheadersize,
				    &pictheader, &pictheadersize);
      bufsize = 0;
      for (ix = 0; seqheadersize[ix] != 0; ix++) {
	bufsize += seqheadersize[ix] + 4;
      }
      for (ix = 0; pictheadersize[ix] != 0; ix++) {
	bufsize += pictheadersize[ix] + 4;
      }
      foo = (uint8_t *)malloc(bufsize + 4);
      memset(foo, 0, bufsize + 4);
      uint32_t copied = 0;
      // headers do not have the byte stream start code stored in the file
      for (ix = 0; seqheadersize[ix] != 0; ix++) {
	foo[copied] = 0;
	foo[copied + 1] = 0;
	foo[copied + 2] = 0;
	foo[copied + 3] = 1;
	copied += 4; // add header
	memcpy(foo + copied, 
	       seqheader[ix], 
	       seqheadersize[ix]);
	copied += seqheadersize[ix];
	free(seqheader[ix]);
      }
      free(seqheader);
      free(seqheadersize);
      for (ix = 0; pictheadersize[ix] != 0; ix++) {
	foo[copied] = 0;
	foo[copied + 1] = 0;
	foo[copied + 2] = 0;
	foo[copied + 3] = 1;
	copied += 4; // add header
	memcpy(foo + copied, 
	       pictheader[ix], 
	       pictheadersize[ix]);
	copied += pictheadersize[ix];
	free(pictheader[ix]);
      }
      free(pictheader);
      free(pictheadersize);
	
      vq[video_offset].type = level;
      vq[video_offset].profile = profile;
      vq[video_offset].fptr = NULL;
      vq[video_offset].config = foo;
      vq[video_offset].config_len = bufsize;
    } else {
      MP4GetTrackVideoMetadata(m_mp4file, trackId, &foo, &bufsize);
      vq[video_offset].config = foo;
      vq[video_offset].config_len = bufsize;
    }

      
    plugin = check_for_video_codec(vq[video_offset].stream_type,
				   vq[video_offset].compressor,
				   NULL,
				   vq[video_offset].type,
				   vq[video_offset].profile,
				   vq[video_offset].config,
				   vq[video_offset].config_len,
				   &config);
    if (plugin == NULL) {
      psptr->set_message("Can't find plugin for video %s type %d, profile %d",
			 vq[video_offset].compressor,
			 vq[video_offset].type, 
			 vq[video_offset].profile);
      m_illegal_video_codec++;
      ret_value = 1;
      // possibly memleak for foo here
    } else {
      vq[video_offset].h = MP4GetTrackVideoHeight(m_mp4file, trackId);
      vq[video_offset].w = MP4GetTrackVideoWidth(m_mp4file, trackId);
      vq[video_offset].frame_rate = MP4GetTrackVideoFrameRate(m_mp4file, trackId);
      vq[video_offset].enabled = 0;
      vq[video_offset].reference = NULL;
      video_offset++;
    }
  }

  audio_offset = 0;
  if (have_audio_driver) {
    for (ix = 0; ix < audio_count; ix++) {
      trackId = MP4FindTrackId(m_mp4file, ix, MP4_AUDIO_TRACK_TYPE);
      const char *media_data_name;
      media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId);

      aq[audio_offset].track_id = trackId;
      aq[audio_offset].stream_type = STREAM_TYPE_MP4_FILE;
      aq[audio_offset].compressor = media_data_name;
      if (strcasecmp(media_data_name, "mp4a") == 0 ||
	  strcasecmp(media_data_name, "enca") == 0) {
	uint8_t *userdata = NULL;
	u_int32_t userdata_size;
	aq[audio_offset].type = MP4GetTrackEsdsObjectTypeId(m_mp4file, trackId);
	MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR));
	aq[audio_offset].profile = MP4GetAudioProfileLevel(m_mp4file);
	MP4GetTrackESConfiguration(m_mp4file, 
				   trackId, 
				   &userdata, 
				   &userdata_size);
	MP4SetVerbosity(m_mp4file, verb);
	aq[audio_offset].config = userdata;
	aq[audio_offset].config_len = userdata_size;
      }
      plugin = check_for_audio_codec(aq[audio_offset].stream_type,
				     aq[audio_offset].compressor,
				     NULL,
				     aq[audio_offset].type,
				     aq[audio_offset].profile,
				     aq[audio_offset].config,
				     aq[audio_offset].config_len,
				     &config);
      if (plugin != NULL) {
	aq[audio_offset].fptr = NULL;
	aq[audio_offset].sampling_freq = 
	  MP4GetTrackTimeScale(m_mp4file, trackId);
	MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR));
	aq[audio_offset].chans = MP4GetTrackAudioChannels(m_mp4file, trackId);
	MP4SetVerbosity(m_mp4file, verb);
	aq[audio_offset].enabled = 0;
	aq[audio_offset].reference = NULL;
	audio_offset++;
	m_have_audio = true;
      } else {
	m_illegal_audio_codec++;
	ret_value = 1;
      }
    }
  } else {
    if (audio_count)
      ret_value = 1;
  }
  text_offset = 0;
  for (ix = 0; ix < text_count; ix++) {
    trackId = MP4FindTrackId(m_mp4file, ix, MP4_CNTL_TRACK_TYPE);
    const char *media_data_name;
    media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId);

    tq[text_offset].track_id = trackId;
    tq[text_offset].stream_type = STREAM_TYPE_MP4_FILE;
    tq[text_offset].compressor = media_data_name;
    plugin = check_for_text_codec(tq[text_offset].stream_type,
				  tq[text_offset].compressor,
				  NULL,
				  NULL,
				  0, 
				  &config);
    if (plugin != NULL) {
      tq[text_offset].fptr = NULL;
      tq[text_offset].enabled = 0;
      tq[text_offset].reference = NULL;
      text_offset++;
    } else {
      m_illegal_text_codec++;
      ret_value = 1;
    }
  }

  if (video_offset == 0 && audio_offset == 0 && text_offset == 0) {
    psptr->set_message("No playable codecs in mp4 file");
    return -1;
  }
  if (cc_vft && cc_vft->media_list_query != NULL) {
    (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq, text_offset, tq);
  } else {
    if (video_offset > 0) {
      vq[0].enabled = 1;
    }
    if (audio_offset > 0) {
      aq[0].enabled = 1;
    }
    if (text_offset > 0) {
      tq[0].enabled = 1;
    }
  }

  int vidret, audret, textret;
  uint start_desc = 1;
  vidret = create_video(psptr, vq, video_offset, start_desc);
  free(vq);

  if (vidret < 0) {
    free(aq);
    free(tq);
    return -1;
  }
 
  audret = create_audio(psptr, aq, audio_offset, start_desc);
  free(aq);

  textret = create_text(psptr, tq, text_offset, start_desc);
  free(tq);

  if (audret < 0 || textret < 0) ret_value = -1;

  char *name;
  verb = MP4GetVerbosity(m_mp4file);
  MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR));
  if (MP4GetMetadataName(m_mp4file, &name) &&
      name != NULL) {
    psptr->set_session_desc(0, name);
    free(name);
  }
  MP4SetVerbosity(m_mp4file, verb);
  
  return (ret_value);
}
Esempio n. 3
0
extern "C" bool MP4AV_Rfc2429Hinter (MP4FileHandle file,
				     MP4TrackId mediaTrackId,
				     uint16_t maxPayloadSize)
{
  uint32_t numSamples, maxSampleSize;
  MP4TrackId hid;
  MP4Duration duration;

  numSamples = MP4GetTrackNumberOfSamples(file, mediaTrackId);
  if (numSamples == 0) {
    return false;
  }
  maxSampleSize = MP4GetTrackMaxSampleSize(file, mediaTrackId);
  u_int8_t* pSampleBuffer = (u_int8_t*)malloc(maxSampleSize);
  if (pSampleBuffer == NULL) {
    return false;
  }

  hid = MP4AddHintTrack(file, mediaTrackId);
  if (hid == MP4_INVALID_TRACK_ID) {
    return false;
  }

  uint8_t payloadNumber = MP4_SET_DYNAMIC_PAYLOAD;
  MP4SetHintTrackRtpPayload(file,
                            hid,
                            "H263-2000",
                            &payloadNumber,
                            0,
                            NULL,
                            true,
                            false);

  // strictly speaking, this is not required for H.263 - it's a quicktime
  // thing.
  u_int16_t videoWidth = MP4GetTrackVideoWidth(file, mediaTrackId);
  u_int16_t videoHeight = MP4GetTrackVideoHeight(file, mediaTrackId);
  
  char sdpString[80];
  sprintf(sdpString, "a=cliprect:0,0,%d,%d\015\012", videoHeight, videoWidth);
  
  MP4AppendHintTrackSdp(file, 
 			hid,
 			sdpString);

  for (uint32_t sid = 1; sid <= numSamples; sid++) {

    duration = MP4GetSampleDuration(file, mediaTrackId, sid);

    MP4AddRtpVideoHint(file, hid, false, 0);

    u_int32_t sampleSize = maxSampleSize;
    MP4Timestamp startTime;
    MP4Duration duration;
    MP4Duration renderingOffset;
    bool isSyncSample;

    bool rc = MP4ReadSample(file, mediaTrackId, sid,
                            &pSampleBuffer, &sampleSize,
                            &startTime, &duration,
                            &renderingOffset, &isSyncSample);

    if (!rc) {
      MP4DeleteTrack(file, hid);
      free(pSampleBuffer);
      return false;
    }

    // need to skip the first 2 bytes of the packet - it is the
    //start code
    uint16_t payload_head = htons(0x400);
    uint32_t offset = sizeof(payload_head);
    uint32_t remaining = sampleSize - sizeof(payload_head);
    while (remaining) {
      bool last_pak = false;
      uint32_t len;

      if (remaining + 2 <= maxPayloadSize) {
        len = remaining;
        last_pak = true;
      } else {
        len = maxPayloadSize - 2;
      }
      MP4AddRtpPacket(file, hid, last_pak);

      MP4AddRtpImmediateData(file, hid,
                            (u_int8_t*)&payload_head, sizeof(payload_head));
      payload_head = 0;
      MP4AddRtpSampleData(file, hid, sid,
                          offset, len);
      offset += len;
      remaining -= len;
    }
    MP4WriteRtpHint(file, hid, duration, true);
  }

  free(pSampleBuffer);

  return true;
}
Esempio n. 4
0
 extern "C" MP4TrackId MP4AV_AVSM_HintTrackCreate (MP4FileHandle mp4File,
						  MP4TrackId mediaTrackId)
{
  MP4TrackId hintTrackId =
    MP4AddHintTrack(mp4File, mediaTrackId);						//添加hint相关的原子mdia.minf.hmhd;mdia.minf.stbl.stsd.rtp
																//mdia.minf.stbl.stsd.rtp .tims.timeScale;tref.hint;udta.hnti.sdp
																//udta.hinf
 
  
  if (hintTrackId == MP4_INVALID_TRACK_ID) {					
    return MP4_INVALID_TRACK_ID;
  }

  u_int8_t payloadNumber = MP4_SET_DYNAMIC_PAYLOAD;

  // don't include mpeg4-esid
  MP4SetHintTrackRtpPayload(mp4File, hintTrackId, 
			    "AVSM", &payloadNumber, 0,						//改变名称“H264”
			    NULL, true, false);
				
  // get the mpeg4 video configuration 
  u_int8_t **pSeq, **pPict ;
  u_int32_t *pSeqSize, *pPictSize;								//参数改变
  char *base64;
  uint32_t profile_level;
  char *sprop = NULL;
  uint32_t ix = 0;

 MP4GetTrackAVSMSeqPictHeaders(mp4File,
				mediaTrackId,
				&pSeq,
				&pSeqSize,										//**获得序列头和图像头相关参数pSeq,pSeqSize,pPict,pPictSize
				&pPict,
				&pPictSize);
				      
  if (pSeqSize && pSeqSize[0] != 0) {								//添加seq参数集
    // we have valid sequence and picture headers
    uint8_t *p = pSeq[0];
    if (*p == 0 && p[1] == 0 && 
	(p[2] == 1 || (p[2] == 0 && p[3] == 0))) {
      if (p[2] == 0) p += 4;
      else p += 3;
    }
    profile_level = p[1] << 8 | p[2];
    while (pSeqSize[ix] != 0) {
      base64 = MP4BinaryToBase64(pSeq[ix], pSeqSize[ix]);
      if (sprop == NULL) {
	sprop = strdup(base64);
      } else {
	sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
	strcat(sprop, ",");
	strcat(sprop, base64);
      }
      free(base64);
      free(pSeq[ix]);
      ix++;
    }
    free(pSeq);
    free(pSeqSize);

    ix = 0;
    while (pPictSize[ix] != 0) {									//添加picture参数集
      base64 = MP4BinaryToBase64(pPict[ix], pPictSize[ix]);
      sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
      strcat(sprop, ",");
      strcat(sprop, base64);
      free(base64);
      free(pPict[ix]);
      ix++;
    }																
    free(pPict);
    free(pPictSize);

    // create the appropriate SDP attribute *
    char* sdpBuf = (char*)malloc(strlen(sprop) + 128);				//sdp
	
	u_int16_t svideoWidth = MP4GetTrackVideoWidth(mp4File, mediaTrackId);		
	u_int16_t svideoHeight = MP4GetTrackVideoHeight(mp4File, mediaTrackId);	//********添加********
  
	  
    sprintf(sdpBuf,
		"a=cliprect:0,0,%d,%d\015\012"
	    "a=fmtp:%u profile-level-id=%04x; sprop-parameter-sets=%s; packetization-mode=1\015\012",
	    svideoWidth,
		svideoHeight,
		payloadNumber,
	    profile_level,
	    sprop); 
	  
    /* add this to the track's sdp */
    MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
	  
    free(sprop);
    free(sdpBuf);
  }
  return hintTrackId;
}
Esempio n. 5
0
 unsigned int GetVideoHeight() const
 {
     return MP4GetTrackVideoHeight(handle, video_track_id);
 }
Esempio n. 6
0
static char* PrintVideoInfo(
	MP4FileHandle mp4File,
	MP4TrackId trackId)
{

	static const u_int8_t mpegVideoTypes[] = {
		MP4_MPEG2_SIMPLE_VIDEO_TYPE,	// 0x60
		MP4_MPEG2_MAIN_VIDEO_TYPE,		// 0x61
		MP4_MPEG2_SNR_VIDEO_TYPE,		// 0x62
		MP4_MPEG2_SPATIAL_VIDEO_TYPE,	// 0x63
		MP4_MPEG2_HIGH_VIDEO_TYPE,		// 0x64
		MP4_MPEG2_442_VIDEO_TYPE,		// 0x65
		MP4_MPEG1_VIDEO_TYPE,			// 0x6A
		MP4_JPEG_VIDEO_TYPE,			// 0x6C
		MP4_YUV12_VIDEO_TYPE,
		MP4_H263_VIDEO_TYPE,
		MP4_H261_VIDEO_TYPE,
	};
	static const char* mpegVideoNames[] = {
		"MPEG-2 Simple",
		"MPEG-2 Main",
		"MPEG-2 SNR",
		"MPEG-2 Spatial",
		"MPEG-2 High",
		"MPEG-2 4:2:2",
		"MPEG-1",
		"JPEG",
		"YUV12",
		"H.263",
		"H.261",
	};
	u_int8_t numMpegVideoTypes =
		sizeof(mpegVideoTypes) / sizeof(u_int8_t);
	bool foundTypeName = false;
	const char* typeName = "Unknown";

	const char *media_data_name;
	char originalFormat[8];
	char  oformatbuffer[32];
	originalFormat[0] = 0;
	*oformatbuffer = 0;
	uint8_t type = 0;
	
	media_data_name = MP4GetTrackMediaDataName(mp4File, trackId);
	// encv 264b
	if (strcasecmp(media_data_name, "encv") == 0) {
	  if (MP4GetTrackMediaDataOriginalFormat(mp4File, 
						 trackId, 
						 originalFormat, 
						 sizeof(originalFormat)) == false)
	      media_data_name = NULL;
	      
	}
  
	char  typebuffer[80];
	if (media_data_name == NULL) {
	  typeName = "Unknown - no media data name";
	  foundTypeName = true;
	} else if ((strcasecmp(media_data_name, "avc1") == 0) ||
	  	(strcasecmp(originalFormat, "264b") == 0)) {
	  // avc
	  uint8_t profile, level;
	  char profileb[20], levelb[20];
	  if (MP4GetTrackH264ProfileLevel(mp4File, trackId, 
					  &profile, &level)) {
	    if (profile == 66) {
	      strcpy(profileb, "Baseline");
	    } else if (profile == 77) {
	      strcpy(profileb, "Main");
	    } else if (profile == 88) {
	      strcpy(profileb, "Extended");
	    } else if (profile == 100) {
	      strcpy(profileb, "High");
	    } else if (profile == 110) {
	      strcpy(profileb, "High 10");
	    } else if (profile == 122) {
	      strcpy(profileb, "High 4:2:2");
	    } else if (profile == 144) {
	      strcpy(profileb, "High 4:4:4");
	    } else {
	      snprintf(profileb, 20, "Unknown Profile %x", profile);
	    } 
	    switch (level) {
	    case 10: case 20: case 30: case 40: case 50:
	      snprintf(levelb, 20, "%u", level / 10);
	      break;
	    case 11: case 12: case 13:
	    case 21: case 22:
	    case 31: case 32:
	    case 41: case 42:
	    case 51:
	      snprintf(levelb, 20, "%u.%u", level / 10, level % 10);
	      break;
	    default:
	      snprintf(levelb, 20, "unknown level %x", level);
	      break;
	    }
	    if (originalFormat != NULL && originalFormat[0] != '\0') 
	      snprintf(oformatbuffer, 32, "(%s) ", originalFormat);
	    snprintf(typebuffer, sizeof(typebuffer), "H264 %s%s@%s", 
		    oformatbuffer, profileb, levelb);
	    typeName = typebuffer;
	  } else {
	    typeName = "H.264 - profile/level error";
	  }
	  foundTypeName = true;
	} else if (strcasecmp(media_data_name, "s263") == 0) {
	  // 3gp h.263
	  typeName = "H.263";
	  foundTypeName = true;
	} else if ((strcasecmp(media_data_name, "mp4v") == 0) ||
		   (strcasecmp(media_data_name, "encv") == 0)) {
	  // note encv might needs it's own field eventually.
	  type = MP4GetTrackEsdsObjectTypeId(mp4File, trackId);
	  if (type == MP4_MPEG4_VIDEO_TYPE) {
	    type = MP4GetVideoProfileLevel(mp4File, trackId);
	    typeName = Mpeg4VisualProfileName(type);
	    if (typeName == NULL) {
	      typeName = "MPEG-4 Unknown Profile";
	    } else {
	      foundTypeName = true;
	    }
	  } else {
	    for (u_int8_t i = 0; i < numMpegVideoTypes; i++) {
	      if (type == mpegVideoTypes[i]) {
		typeName = mpegVideoNames[i];
		foundTypeName = true;
		break;
	      }
	    }
	  }
	} else {
	  typeName = media_data_name;
	  foundTypeName = true; // we don't have a type value to display
	}

	MP4Duration trackDuration =
		MP4GetTrackDuration(mp4File, trackId);

	double msDuration =
		UINT64_TO_DOUBLE(MP4ConvertFromTrackDuration(mp4File, trackId,
			trackDuration, MP4_MSECS_TIME_SCALE));

	u_int32_t avgBitRate =
		MP4GetTrackBitRate(mp4File, trackId);

	// Note not all mp4 implementations set width and height correctly
	// The real answer can be buried inside the ES configuration info
	u_int16_t width = MP4GetTrackVideoWidth(mp4File, trackId);

	u_int16_t height = MP4GetTrackVideoHeight(mp4File, trackId);

	double fps = MP4GetTrackVideoFrameRate(mp4File, trackId);

	char *sInfo = (char*)MP4Malloc(256);

	// type duration avgBitrate frameSize frameRate
	if (foundTypeName) {
	  sprintf(sInfo,
		  "%u\tvideo\t%s%s, %.3f secs, %u kbps, %ux%u @ %f fps\n",
		  trackId,
		  MP4IsIsmaCrypMediaTrack(mp4File, trackId) ? "encv - " : "",
		  typeName,
		  msDuration / 1000.0,
		  (avgBitRate + 500) / 1000,
		  width,
		  height,
		  fps
		  );
	} else {
	  sprintf(sInfo,
		  "%u\tvideo\t%s(%u), %.3f secs, %u kbps, %ux%u @ %f fps\n",
		  trackId,
		  typeName,
		  type, 
		  msDuration / 1000.0,
		  (avgBitRate + 500) / 1000,
		  width,
		  height,
		  fps
		  );
	}

	return sInfo;
}
Esempio n. 7
0
static GtkWidget* CreateMp4TrackMenu(
	GtkWidget* menu,
	char type,
	const char* source,
	u_int32_t* pIndex,
	u_int32_t* pNumber,
	u_int32_t** ppValues)
{
	*pIndex = 0;

	u_int32_t newTrackNumber = 1;

	MP4FileHandle mp4File = MP4Read(source);

	char* trackType = NULL;

	if (mp4File) {
		if (type == 'V') {
			trackType = MP4_VIDEO_TRACK_TYPE;
		} else {
			trackType = MP4_AUDIO_TRACK_TYPE;
		}
		newTrackNumber = 
			MP4GetNumberOfTracks(mp4File, trackType);
	}

	u_int32_t* newTrackValues = 
		(u_int32_t*)malloc(sizeof(u_int32_t) * newTrackNumber);

	char** newTrackNames = 
		(char**)malloc(sizeof(char*) * newTrackNumber);

	if (!mp4File) {
		newTrackValues[0] = 0;
		newTrackNames[0] = strdup("");
	} else {
		for (u_int8_t i = 0; i < newTrackNumber; i++) {
			MP4TrackId trackId =
				MP4FindTrackId(mp4File, i, trackType);

			char* trackName = "Unknown";
			char buf[64];

			if (trackType == MP4_VIDEO_TRACK_TYPE) {
				u_int8_t videoType =
					MP4GetTrackEsdsObjectTypeId(mp4File, 
								    trackId);

				switch (videoType) {
				case MP4_MPEG1_VIDEO_TYPE:
					trackName = "MPEG1";
					break;
				case MP4_MPEG2_SIMPLE_VIDEO_TYPE:
				case MP4_MPEG2_MAIN_VIDEO_TYPE:
				case MP4_MPEG2_SNR_VIDEO_TYPE:
				case MP4_MPEG2_SPATIAL_VIDEO_TYPE:
				case MP4_MPEG2_HIGH_VIDEO_TYPE:
				case MP4_MPEG2_442_VIDEO_TYPE:
					trackName = "MPEG2";
					break;
				case MP4_MPEG4_VIDEO_TYPE:
					trackName = "MPEG4";
					break;
				case MP4_YUV12_VIDEO_TYPE:
					trackName = "YUV12";
					break;
				case MP4_H263_VIDEO_TYPE:
					trackName = "H263";
					break;
				case MP4_H261_VIDEO_TYPE:
					trackName = "H261";
					break;
				}
			
				snprintf(buf, sizeof(buf), 
					"%u - %s %u x %u %.2f fps %u kbps", 
					trackId, 
					trackName,
					MP4GetTrackVideoWidth(mp4File, trackId),
					MP4GetTrackVideoHeight(mp4File, trackId),
					MP4GetTrackVideoFrameRate(mp4File, trackId),
					(MP4GetTrackBitRate(mp4File, trackId) + 500) / 1000);

			} else { // audio
				u_int8_t audioType =
					MP4GetTrackEsdsObjectTypeId(mp4File, 
								    trackId);

				switch (audioType) {
				case MP4_MPEG1_AUDIO_TYPE:
				case MP4_MPEG2_AUDIO_TYPE:
					trackName = "MPEG (MP3)";
					break;
				case MP4_MPEG2_AAC_MAIN_AUDIO_TYPE:
				case MP4_MPEG2_AAC_LC_AUDIO_TYPE:
				case MP4_MPEG2_AAC_SSR_AUDIO_TYPE:
				case MP4_MPEG4_AUDIO_TYPE:
					trackName = "AAC";
					break;
				case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE:
					trackName = "PCM16 LITTLE ENDIAN";
					break;
				case MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE:
				  trackName = "PCM16 BIG ENDIAN";
				case MP4_AC3_AUDIO_TYPE:
					trackName = "AC3";
					break;
				case MP4_VORBIS_AUDIO_TYPE:
					trackName = "Ogg Vorbis";
					break;
				case MP4_ALAW_AUDIO_TYPE:
					trackName = "G711 aLaw";
					break;
				case MP4_ULAW_AUDIO_TYPE:
					trackName = "G711 uLaw";
					break;
				}

				snprintf(buf, sizeof(buf), 
					"%u - %s %u kbps", 
					trackId, 
					trackName,
					(MP4GetTrackBitRate(mp4File, trackId) + 500) / 1000);
			}

			newTrackValues[i] = trackId;
			newTrackNames[i] = strdup(buf);
		}

		MP4Close(mp4File);
	}

	// (re)create the menu
	menu = CreateOptionMenu(
		menu,
		newTrackNames, 
		newTrackNumber,
		*pIndex,
		GTK_SIGNAL_FUNC(on_track_menu_activate));

	// free up old names
	for (u_int8_t i = 0; i < *pNumber; i++) {
		free(trackNames[i]);
	}
	free(trackNames);
	free(*ppValues);

	*pNumber = newTrackNumber;
	trackNames = newTrackNames;
	*ppValues = newTrackValues;

	return menu;
}
Esempio n. 8
0
DWORD MP4Streamer::GetVideoHeight()
{
	return MP4GetTrackVideoHeight(video->mp4,video->track);
}