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

流媒体/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. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. // N.B. mp4extract just extracts tracks/samples from an mp4 file
  22. // For many track types this is insufficient to reconsruct a valid
  23. // elementary stream (ES). Use "mp4creator -extract=<trackId>" if
  24. // you need the ES reconstructed. 
  25. #include "mp4.h"
  26. #include "mpeg4ip_getopt.h"
  27. char* ProgName;
  28. char* Mp4PathName;
  29. char* Mp4FileName;
  30. // forward declaration
  31. void ExtractTrack(MP4FileHandle mp4File, MP4TrackId trackId, 
  32. bool sampleMode, MP4SampleId sampleId, char* dstFileName = NULL);
  33. int main(int argc, char** argv)
  34. {
  35. char* usageString = 
  36. "usage: %s [-l] [-t <track-id>] [-s <sample-id>] [-v [<level>]] <file-name>n";
  37. bool doList = false;
  38. bool doSamples = false;
  39. MP4TrackId trackId = MP4_INVALID_TRACK_ID;
  40. MP4SampleId sampleId = MP4_INVALID_SAMPLE_ID;
  41. char* dstFileName = NULL;
  42. u_int32_t verbosity = MP4_DETAILS_ERROR;
  43. /* begin processing command line */
  44. ProgName = argv[0];
  45. while (true) {
  46. int c = -1;
  47. int option_index = 0;
  48. static struct option long_options[] = {
  49. { "list", 0, 0, 'l' },
  50. { "track", 1, 0, 't' },
  51. { "sample", 2, 0, 's' },
  52. { "verbose", 2, 0, 'v' },
  53. { "version", 0, 0, 'V' },
  54. { NULL, 0, 0, 0 }
  55. };
  56. c = getopt_long_only(argc, argv, "lt:s::v::V",
  57. long_options, &option_index);
  58. if (c == -1)
  59. break;
  60. switch (c) {
  61. case 'l':
  62. doList = true;
  63. break;
  64. case 's':
  65. doSamples = true;
  66. if (optarg) {
  67. if (sscanf(optarg, "%u", &sampleId) != 1) {
  68. fprintf(stderr, 
  69. "%s: bad sample-id specified: %sn",
  70.  ProgName, optarg);
  71. }
  72. }
  73. break;
  74. case 't':
  75. if (sscanf(optarg, "%u", &trackId) != 1) {
  76. fprintf(stderr, 
  77. "%s: bad track-id specified: %sn",
  78.  ProgName, optarg);
  79. exit(1);
  80. }
  81. break;
  82. case 'v':
  83. verbosity |= MP4_DETAILS_READ;
  84. if (optarg) {
  85. u_int32_t level;
  86. if (sscanf(optarg, "%u", &level) == 1) {
  87. if (level >= 2) {
  88. verbosity |= MP4_DETAILS_TABLE;
  89. if (level >= 3) {
  90. verbosity |= MP4_DETAILS_SAMPLE;
  91. if (level >= 4) {
  92. verbosity = MP4_DETAILS_ALL;
  93. }
  94. }
  95. }
  96. break;
  97. case '?':
  98. fprintf(stderr, usageString, ProgName);
  99. exit(0);
  100. case 'V':
  101.   fprintf(stderr, "%s - %s version %sn", 
  102.   ProgName, PACKAGE, VERSION);
  103.   exit(0);
  104. default:
  105. fprintf(stderr, "%s: unknown option specified, ignoring: %cn", 
  106. ProgName, c);
  107. }
  108. }
  109. /* check that we have at least one non-option argument */
  110. if ((argc - optind) < 1) {
  111. fprintf(stderr, usageString, ProgName);
  112. exit(1);
  113. }
  114. if (verbosity) {
  115. fprintf(stderr, "%s version %sn", ProgName, VERSION);
  116. }
  117. /* point to the specified file names */
  118. Mp4PathName = argv[optind++];
  119. /* get dest file name for a single track */
  120. if (trackId && (argc - optind) > 0) {
  121. dstFileName = argv[optind++];
  122. }
  123. char* lastSlash = strrchr(Mp4PathName, '/');
  124. if (lastSlash) {
  125. Mp4FileName = lastSlash + 1;
  126. } else {
  127. Mp4FileName = Mp4PathName; 
  128. }
  129. /* warn about extraneous non-option arguments */
  130. if (optind < argc) {
  131. fprintf(stderr, "%s: unknown options specified, ignoring: ", ProgName);
  132. while (optind < argc) {
  133. fprintf(stderr, "%s ", argv[optind++]);
  134. }
  135. fprintf(stderr, "n");
  136. }
  137. /* end processing of command line */
  138. MP4FileHandle mp4File = MP4Read(Mp4PathName, verbosity);
  139. if (!mp4File) {
  140. exit(1);
  141. }
  142. if (doList) {
  143. MP4Info(mp4File);
  144. exit(0);
  145. }
  146. if (trackId == 0) {
  147. u_int32_t numTracks = MP4GetNumberOfTracks(mp4File);
  148. for (u_int32_t i = 0; i < numTracks; i++) {
  149. trackId = MP4FindTrackId(mp4File, i);
  150. ExtractTrack(mp4File, trackId, doSamples, sampleId);
  151. }
  152. } else {
  153. ExtractTrack(mp4File, trackId, doSamples, sampleId, dstFileName);
  154. }
  155. MP4Close(mp4File);
  156. return(0);
  157. }
  158. void ExtractTrack(MP4FileHandle mp4File, MP4TrackId trackId, 
  159. bool sampleMode, MP4SampleId sampleId, char* dstFileName)
  160. {
  161. char outFileName[PATH_MAX];
  162. int outFd = -1;
  163. if (!sampleMode) {
  164. if (dstFileName == NULL) {
  165. snprintf(outFileName, sizeof(outFileName), 
  166. "%s.t%u", Mp4FileName, trackId);
  167. } else {
  168. snprintf(outFileName, sizeof(outFileName), 
  169. "%s", dstFileName);
  170. }
  171. outFd = open(outFileName, 
  172. O_WRONLY | O_CREAT | O_TRUNC, 0644);
  173. if (outFd == -1) {
  174. fprintf(stderr, "%s: can't open %s: %sn",
  175. ProgName, outFileName, strerror(errno));
  176. return;
  177. }
  178. }
  179. MP4SampleId numSamples;
  180. if (sampleMode && sampleId != MP4_INVALID_SAMPLE_ID) {
  181. numSamples = sampleId;
  182. } else {
  183. sampleId = 1;
  184. numSamples = MP4GetTrackNumberOfSamples(mp4File, trackId);
  185. }
  186. u_int8_t* pSample;
  187. u_int32_t sampleSize;
  188. for ( ; sampleId <= numSamples; sampleId++) {
  189. int rc;
  190. // signals to ReadSample() that it should malloc a buffer for us
  191. pSample = NULL;
  192. sampleSize = 0;
  193. rc = MP4ReadSample(mp4File, trackId, sampleId, &pSample, &sampleSize);
  194. if (rc == 0) {
  195. fprintf(stderr, "%s: read sample %u for %s failedn",
  196. ProgName, sampleId, outFileName);
  197. break;
  198. }
  199. if (sampleMode) {
  200. snprintf(outFileName, sizeof(outFileName), "%s.t%u.s%u",
  201. Mp4FileName, trackId, sampleId);
  202. outFd = open(outFileName, 
  203. O_WRONLY | O_CREAT | O_TRUNC, 0644);
  204. if (outFd == -1) {
  205. fprintf(stderr, "%s: can't open %s: %sn",
  206. ProgName, outFileName, strerror(errno));
  207. break;
  208. }
  209. }
  210. rc = write(outFd, pSample, sampleSize);
  211. if (rc == -1 || (u_int32_t)rc != sampleSize) {
  212. fprintf(stderr, "%s: write to %s failed: %sn",
  213. ProgName, outFileName, strerror(errno));
  214. break;
  215. }
  216. free(pSample);
  217. if (sampleMode) {
  218. close(outFd);
  219. outFd = -1;
  220. }
  221. }
  222. if (outFd != -1) {
  223. close(outFd);
  224. }
  225. }