xvidenc.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:

流媒体/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 <mpeg4ip.h>
  26. #include <sys/types.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <errno.h>
  30. #include <string.h>
  31. #include <mpeg4ip_getopt.h>
  32. #include <fcntl.h>
  33. #include <math.h>
  34. #include <time.h>
  35. #include <divx4.h>
  36. /* globals */
  37. char* progName;
  38. /*
  39.  * xvidenc
  40.  * required arg1 should be the raw file to be encoded
  41.  * required arg2 should be the target encoded file (MPEG-4 ES)
  42.  */ 
  43. int main(int argc, char** argv)
  44. {
  45. /* variables controlable from command line */
  46. u_int bitRate = 500000; /* --bitrate=<uint> */
  47. u_int frameWidth = 320; /* --width=<uint> */
  48. u_int frameHeight = 240; /* --height=<uint> */
  49. float frameRate = 30.0; /* --rate=<float> */
  50. u_int iFrameFrequency = 30; /* --ifrequency=<uint> */
  51. /* internal variables */
  52. char* rawFileName = NULL;
  53. char* mpeg4FileName = NULL;
  54. FILE* rawFile = NULL;
  55. FILE* mpeg4File = NULL;
  56. void* myHandle = NULL;
  57. ENC_PARAM encParams;
  58. ENC_FRAME encFrame;
  59. ENC_RESULT encResult;
  60. u_int32_t yuvSize;
  61. u_int8_t encVopBuffer[128 * 1024];
  62. u_int32_t frameNumber = 0;
  63. time_t startTime;
  64. /* begin process command line */
  65. progName = argv[0];
  66. while (1) {
  67. int c = -1;
  68. int option_index = 0;
  69. static struct option long_options[] = {
  70. { "bitrate", 1, 0, 'b' },
  71. { "height", 1, 0, 'h' },
  72. { "ifrequency", 1, 0, 'i' },
  73. { "rate", 1, 0, 'r' },
  74. { "width", 1, 0, 'w' },
  75. { NULL, 0, 0, 0 }
  76. };
  77. c = getopt_long_only(argc, argv, "b:h:i:r:w:",
  78. long_options, &option_index);
  79. if (c == -1)
  80. break;
  81. switch (c) {
  82. case 'b': {
  83. /* --bitrate <Kbps> */
  84. u_int i;
  85. if (sscanf(optarg, "%u", &i) < 1) {
  86. fprintf(stderr, 
  87. "%s: bad bitrate specified: %sn",
  88.  progName, optarg);
  89. } else {
  90. /* currently no range checking */
  91. bitRate = i * 1000;
  92. }
  93. break;
  94. }
  95. case 'h': {
  96. /* --height <pixels> */
  97. u_int i;
  98. if (sscanf(optarg, "%u", &i) < 1) {
  99. fprintf(stderr, 
  100. "%s: bad height specified: %sn",
  101.  progName, optarg);
  102. } else {
  103. /* currently no range checking */
  104. frameHeight = i;
  105. }
  106. break;
  107. }
  108. case 'i': {
  109. u_int i;
  110. if (sscanf(optarg, "%u", &i) < 1) {
  111. fprintf(stderr, 
  112. "%s: bad ifrequency specified: %sn",
  113.  progName, optarg);
  114. } else {
  115. iFrameFrequency = i;
  116. }
  117. break;
  118. }
  119. case 'r': {
  120. /* -rate <fps> */
  121. float f;
  122. if (sscanf(optarg, "%f", &f) < 1) {
  123. fprintf(stderr, 
  124. "%s: bad rate specified: %sn",
  125.  progName, optarg);
  126. } else if (f < 1.0 || f > 30.0) {
  127. fprintf(stderr,
  128. "%s: rate must be between 1 and 30n",
  129. progName);
  130. } else {
  131. frameRate = f;
  132. }
  133. break;
  134. }
  135. case 'w': {
  136. /* -width <pixels> */
  137. u_int i;
  138. if (sscanf(optarg, "%u", &i) < 1) {
  139. fprintf(stderr, 
  140. "%s: bad width specified: %sn",
  141.  progName, optarg);
  142. } else {
  143. /* currently no range checking */
  144. frameWidth = i;
  145. }
  146. break;
  147. }
  148. case '?':
  149. break;
  150. default:
  151. fprintf(stderr, "%s: unknown option specified, ignoring: %cn",
  152. progName, c);
  153. }
  154. }
  155. /* check that we have at least two non-option arguments */
  156. if ((argc - optind) < 2) {
  157. fprintf(stderr, 
  158. "usage: %s <raw-file> <mpeg4-file>n",
  159. progName);
  160. exit(1);
  161. }
  162. /* point to the specified file names */
  163. rawFileName = argv[optind++];
  164. mpeg4FileName = argv[optind++];
  165. /* warn about extraneous non-option arguments */
  166. if (optind < argc) {
  167. fprintf(stderr, "%s: unknown options specified, ignoring: ", progName);
  168. while (optind < argc) {
  169. fprintf(stderr, "%s ", argv[optind++]);
  170. }
  171. fprintf(stderr, "n");
  172. }
  173. /* end processing of command line */
  174. /* open raw file for reading */
  175. rawFile = fopen(rawFileName, "rb");
  176. if (rawFile == NULL) {
  177. /* error, file doesn't exist or we can't read it */
  178. fprintf(stderr,
  179. "%s: error opening %s: %sn",
  180. progName, rawFileName, strerror(errno));
  181. exit(2);
  182. }
  183. /* open the MPEG-4 file for writing */
  184. mpeg4File = fopen(mpeg4FileName, "wb");
  185. if (mpeg4File == NULL) {
  186. fprintf(stderr, 
  187. "%s: error %s: %sn",
  188. progName, mpeg4FileName, strerror(errno));
  189. fclose(rawFile);
  190. exit(4);
  191. }
  192. /* initialize encoder */
  193. encParams.x_dim = frameWidth;
  194. encParams.y_dim = frameHeight;
  195. encParams.framerate = frameRate;
  196. encParams.bitrate = bitRate;
  197. encParams.rc_period = 2000;
  198. encParams.rc_reaction_period = 10;
  199. encParams.rc_reaction_ratio = 20;
  200. encParams.max_key_interval = iFrameFrequency;
  201. encParams.use_bidirect = 0;
  202. encParams.deinterlace = 0;
  203. encParams.quality = 5;
  204. encParams.obmc = 0;
  205. encParams.handle = NULL;
  206. if (encore(myHandle, ENC_OPT_INIT, &encParams, NULL) != ENC_OK) {
  207. fprintf(stderr, 
  208. "%s: error: can't initialize encodern",
  209. progName);
  210. exit(5);
  211. }
  212. myHandle = encParams.handle;
  213. yuvSize = (frameWidth * frameHeight * 3) / 2;
  214. encFrame.image = (u_int8_t *)malloc(yuvSize);
  215. encFrame.bitstream = encVopBuffer;
  216. encFrame.colorspace = ENC_CSP_I420;
  217. encFrame.quant = 0;
  218. encFrame.intra = -1;
  219. encFrame.mvs = NULL;
  220. startTime = time(0);
  221. while (!feof(rawFile)) {
  222. int rc;
  223. frameNumber++;
  224. /* read yuv data */
  225. rc = fread(encFrame.image, sizeof(u_int8_t), yuvSize, rawFile);
  226. if (rc == 0) {
  227. break;
  228. }
  229. if (rc != yuvSize) {
  230. fprintf(stderr, 
  231. "%s: read error %s on frame %d: %sn",
  232. progName, rawFileName, frameNumber, strerror(errno));
  233. break;
  234. }
  235. encFrame.length = sizeof(encVopBuffer);
  236. /* call xvid encoder */
  237. rc = encore(myHandle, ENC_OPT_ENCODE, &encFrame, &encResult);
  238. if (rc != ENC_OK) {
  239. if (rc == ENC_MEMORY) {
  240. fprintf(stderr, 
  241. "%s: encode error %s: memoryn",
  242. progName, mpeg4FileName);
  243. } else if (rc == ENC_BAD_FORMAT) {
  244. fprintf(stderr, 
  245. "%s: encode error %s: bad formatn",
  246. progName, mpeg4FileName);
  247. } else {
  248. fprintf(stderr, 
  249. "%s: encode error %s: unknown error %dn",
  250. progName, mpeg4FileName, rc);
  251. }
  252. break;
  253. }
  254. /* write results to output file */
  255. rc = fwrite(encFrame.bitstream, 1, encFrame.length, mpeg4File);
  256. if (rc != encFrame.length) {
  257. fprintf(stderr, 
  258. "%s: write error %s: %sn",
  259. progName, mpeg4FileName, strerror(errno));
  260. break;
  261. }
  262. /* DEBUG
  263. printf("Encoding frame %u to %lu bytes", frameNumber, encFrame.length);
  264.     */
  265. if (frameNumber > 0 && (frameNumber % (10 * (int)frameRate)) == 0) {
  266. int elapsed = time(0) - startTime;
  267. if (elapsed > 0) {
  268. printf("Encoded %u seconds of video in %u seconds, %u fpsn", 
  269. (int)(frameNumber / frameRate),
  270. elapsed, 
  271. frameNumber / elapsed);
  272. }
  273. }
  274. }
  275. /* cleanup */
  276. encore(myHandle, ENC_OPT_RELEASE, NULL, NULL);
  277. fclose(rawFile);
  278. fclose(mpeg4File);
  279. return(0);
  280. }