rfc3016.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:4k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. /* 
  22.  * Notes:
  23.  *  - file formatted with tabstops == 4 spaces 
  24.  */
  25. #include <mp4av_common.h>
  26. #include <mp4av_mpeg4.h>
  27. extern "C" bool MP4AV_Rfc3016Hinter(
  28. MP4FileHandle mp4File, 
  29. MP4TrackId mediaTrackId, 
  30. u_int16_t maxPayloadSize)
  31. {
  32. MP4TrackId hintTrackId =
  33. MP4AddHintTrack(mp4File, mediaTrackId);
  34. if (hintTrackId == MP4_INVALID_TRACK_ID) {
  35. return false;
  36. }
  37. u_int8_t payloadNumber = 0;
  38. MP4SetHintTrackRtpPayload(mp4File, hintTrackId, 
  39. "MP4V-ES", &payloadNumber, 0);
  40. /* get the mpeg4 video configuration */
  41. u_int8_t* pConfig;
  42. u_int32_t configSize;
  43. u_int8_t systemsProfileLevel = 0xFE;
  44. MP4GetTrackESConfiguration(mp4File, mediaTrackId, &pConfig, &configSize);
  45. if (pConfig) {
  46. // attempt to get a valid profile-level
  47. static u_int8_t voshStartCode[4] = { 
  48. 0x00, 0x00, 0x01, MP4AV_MPEG4_VOSH_START 
  49. };
  50. if (configSize >= 5 && !memcmp(pConfig, voshStartCode, 4)) {
  51. systemsProfileLevel = 
  52. MP4AV_Mpeg4VideoToSystemsProfileLevel(pConfig[4]);
  53. if (systemsProfileLevel == 0xFE) {
  54. u_int8_t iodProfileLevel = MP4GetVideoProfileLevel(mp4File);
  55. if (iodProfileLevel > 0 && iodProfileLevel < 0xFE) {
  56. systemsProfileLevel = iodProfileLevel;
  57. } else {
  58. systemsProfileLevel = 1;
  59. }
  60. /* convert it into ASCII form */
  61. char* sConfig = MP4BinaryToBase16(pConfig, configSize);
  62. if (sConfig == NULL) {
  63. return false;
  64. }
  65. /* create the appropriate SDP attribute */
  66. char* sdpBuf = (char*)malloc(strlen(sConfig) + 128);
  67. sprintf(sdpBuf,
  68. "a=fmtp:%u profile-level-id=%u; config=%s;1512",
  69. payloadNumber,
  70. systemsProfileLevel,
  71. sConfig); 
  72. /* add this to the track's sdp */
  73. MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
  74. free(sConfig);
  75. free(sdpBuf);
  76. }
  77. u_int32_t numSamples = MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
  78. u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);
  79. if (numSamples == 0 || maxSampleSize == 0) {
  80. return false;
  81. }
  82. u_int8_t* pSampleBuffer = (u_int8_t*)malloc(maxSampleSize);
  83. if (pSampleBuffer == NULL) {
  84. return false;
  85. }
  86. for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
  87. u_int32_t sampleSize = maxSampleSize;
  88. MP4Timestamp startTime;
  89. MP4Duration duration;
  90. MP4Duration renderingOffset;
  91. bool isSyncSample;
  92. bool rc = MP4ReadSample(
  93. mp4File, mediaTrackId, sampleId, 
  94. &pSampleBuffer, &sampleSize, 
  95. &startTime, &duration, 
  96. &renderingOffset, &isSyncSample);
  97. if (!rc) {
  98. return false;
  99. }
  100. bool isBFrame = 
  101. (MP4AV_Mpeg4GetVopType(pSampleBuffer, sampleSize) == 'B');
  102. MP4AddRtpVideoHint(mp4File, hintTrackId, isBFrame, renderingOffset);
  103. if (sampleId == 1) {
  104. MP4AddRtpESConfigurationPacket(mp4File, hintTrackId);
  105. }
  106. u_int32_t offset = 0;
  107. u_int32_t remaining = sampleSize;
  108. while (remaining) {
  109. bool isLastPacket = false;
  110. u_int32_t length;
  111. if (remaining <= maxPayloadSize) {
  112. length = remaining;
  113. isLastPacket = true;
  114. } else {
  115. length = maxPayloadSize;
  116. }
  117. MP4AddRtpPacket(mp4File, hintTrackId, isLastPacket);
  118. MP4AddRtpSampleData(mp4File, hintTrackId, sampleId, 
  119. offset, length);
  120. offset += length;
  121. remaining -= length;
  122. }
  123. MP4WriteRtpHint(mp4File, hintTrackId, duration, isSyncSample);
  124. }
  125. return true;
  126. }