xvidenc.c
来自「完整的RTP RTSP代码库」· C语言 代码 · 共 345 行
C
345 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000-2003. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com * Bill May wmay@cisco.com */#include <mpeg4ip.h>#include <sys/types.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <mpeg4ip_getopt.h>#include <fcntl.h>#include <math.h>#include <time.h>#include <xvid.h>#include <mp4av.h>/* globals */char* progName;/* * xvidenc * required arg1 should be the raw file to be encoded * required arg2 should be the target encoded file (MPEG-4 ES) */ static const char *help_str = "usage: %s <yuv file> <output file>\n""--bitrate <brate> target bit rate\n""--height <height> video height\n""--width <height> video width\n""--rate <fps> frames per second\n""--ifrequency <ifreq> iframe frequency in frames\n""--version display version\n";int main(int argc, char** argv){ /* variables controlable from command line */ u_int bitRate = 500000; /* --bitrate=<uint> */ u_int frameWidth = 320; /* --width=<uint> */ u_int frameHeight = 240; /* --height=<uint> */ float frameRate = 30.0; /* --rate=<float> */ u_int iFrameFrequency = 30; /* --ifrequency=<uint> */ /* internal variables */ char* rawFileName = NULL; char* mpeg4FileName = NULL; FILE* rawFile = NULL; FILE* mpeg4File = NULL; XVID_INIT_PARAM xvidInitParams; XVID_ENC_PARAM xvidEncParams; XVID_ENC_FRAME xvidFrame; XVID_DEC_PICTURE decpict; XVID_ENC_STATS xvidResult; void *xvidHandle; u_int32_t yuvSize, ySize; u_int8_t encVopBuffer[128 * 1024]; u_int32_t frameNumber = 0; time_t startTime; int rc; uint8_t *readbuffer; memset(&xvidInitParams, 0, sizeof(xvidInitParams)); if (xvid_init(NULL, 0, &xvidInitParams, NULL) != XVID_ERR_OK) { fprintf(stderr, "%s: failed to initialize xvid\n", progName); exit(5); } /* begin process command line */ progName = argv[0]; while (1) { int c = -1; int option_index = 0; static struct option long_options[] = { { "bitrate", 1, 0, 'b' }, { "height", 1, 0, 'h' }, { "ifrequency", 1, 0, 'i' }, { "rate", 1, 0, 'r' }, { "width", 1, 0, 'w' }, { "version", 0, 0, 'v'}, { NULL, 0, 0, 0 } }; c = getopt_long_only(argc, argv, "b:h:i:r:w:v", long_options, &option_index); if (c == -1) break; switch (c) { case 'b': { /* --bitrate <Kbps> */ u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad bitrate specified: %s\n", progName, optarg); } else { /* currently no range checking */ bitRate = i * 1000; } break; } case 'h': { /* --height <pixels> */ u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad height specified: %s\n", progName, optarg); } else { /* currently no range checking */ frameHeight = i; } break; } case 'i': { u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad ifrequency specified: %s\n", progName, optarg); } else { iFrameFrequency = i; } break; } case 'r': { /* -rate <fps> */ float f; if (sscanf(optarg, "%f", &f) < 1) { fprintf(stderr, "%s: bad rate specified: %s\n", progName, optarg); } else if (f < 1.0 || f > 30.0) { fprintf(stderr, "%s: rate must be between 1 and 30\n", progName); } else { frameRate = f; } break; } case 'w': { /* -width <pixels> */ u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad width specified: %s\n", progName, optarg); } else { /* currently no range checking */ frameWidth = i; } break; } case 'v': fprintf(stdout, "%s version %s\n", MPEG4IP_PACKAGE, MPEG4IP_VERSION); fprintf(stdout, "xvid api version %d\n", xvidInitParams.api_version); fprintf(stdout, "xvid core build %d\n", xvidInitParams.core_build); exit(0); default: fprintf(stderr, "%s: unknown option specified, ignoring: %c\n", progName, c); break; case '?': fprintf(stderr, help_str, progName); exit(0); } } /* check that we have at least two non-option arguments */ if ((argc - optind) < 2) { fprintf(stderr, help_str, progName); exit(1); } /* point to the specified file names */ rawFileName = argv[optind++]; mpeg4FileName = argv[optind++]; /* warn about extraneous non-option arguments */ if (optind < argc) { fprintf(stderr, "%s: unknown options specified, ignoring: ", progName); while (optind < argc) { fprintf(stderr, "%s ", argv[optind++]); } fprintf(stderr, "\n"); } /* end processing of command line */ /* open raw file for reading */ rawFile = fopen(rawFileName, "rb"); if (rawFile == NULL) { /* error, file doesn't exist or we can't read it */ fprintf(stderr, "%s: error opening %s: %s\n", progName, rawFileName, strerror(errno)); exit(2); } /* open the MPEG-4 file for writing */ mpeg4File = fopen(mpeg4FileName, "wb"); if (mpeg4File == NULL) { fprintf(stderr, "%s: error %s: %s\n", progName, mpeg4FileName, strerror(errno)); fclose(rawFile); exit(4); } memset(&xvidEncParams, 0, sizeof(xvidEncParams)); xvidEncParams.width = frameWidth; xvidEncParams.height = frameHeight; xvidEncParams.fincr = 1; xvidEncParams.fbase = (int)(frameRate + 0.5); xvidEncParams.rc_bitrate = bitRate; xvidEncParams.min_quantizer = 1; xvidEncParams.max_quantizer = 31; xvidEncParams.max_key_interval = iFrameFrequency; if (xvidEncParams.max_key_interval == 0) xvidEncParams.max_key_interval = 1; if (xvid_encore(NULL, XVID_ENC_CREATE, &xvidEncParams, NULL) != XVID_ERR_OK) { fprintf(stderr, "%s: failed to initialize xvid encoder params\n", progName); exit(6); } xvidHandle = xvidEncParams.handle; memset(&xvidFrame, 0, sizeof(xvidFrame)); xvidFrame.general = XVID_HALFPEL | XVID_H263QUANT; xvidFrame.motion = PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8; xvidFrame.general |= XVID_INTER4V; xvidFrame.quant = 0; ySize = frameWidth * frameHeight; yuvSize = (ySize * 3) / 2; readbuffer = (uint8_t *)malloc(yuvSize); decpict.y = readbuffer; decpict.u = decpict.y + ySize; decpict.v = decpict.u + ySize / 4; decpict.stride_y = frameWidth; decpict.stride_u = frameWidth / 2; xvidFrame.image = &decpict; xvidFrame.colorspace = XVID_CSP_USER; startTime = time(0); while (!feof(rawFile)) { frameNumber++; /* read yuv data */ rc = fread(readbuffer, sizeof(u_int8_t), yuvSize, rawFile); if (rc == 0) { break; } if (rc == -1) { fprintf(stderr, "%s: read error %s on frame %d: %s\n", progName, rawFileName, frameNumber, strerror(errno)); break; } if (rc != yuvSize) { fprintf(stderr, "%s: read error %s on frame %d: too few bytes, expected %d, got %d\n", progName, rawFileName, frameNumber, yuvSize, rc); break; } xvidFrame.bitstream = encVopBuffer; xvidFrame.intra = -1; // encFrame.length = sizeof(encVopBuffer); /* call xvid encoder */ rc = xvid_encore(xvidHandle, XVID_ENC_ENCODE, &xvidFrame, &xvidResult); if (rc != XVID_ERR_OK) { fprintf(stderr, "%s: encode error %s: unknown error %d\n", progName, mpeg4FileName, rc); } /* write results to output file */ if (frameNumber == 1 && encVopBuffer[3] != MP4AV_MPEG4_VOSH_START) { static uint8_t vosh[] = { 0, 0, 1, MP4AV_MPEG4_VOSH_START,MPEG4_SP_L3, 0, 0, 1, MP4AV_MPEG4_VO_START, 0x08 }; fwrite(vosh, 1, sizeof(vosh), mpeg4File); } rc = fwrite(encVopBuffer, 1, xvidFrame.length, mpeg4File); if (rc != xvidFrame.length) { fprintf(stderr, "%s: write error %s: %s\n", progName, mpeg4FileName, strerror(errno)); } /* DEBUG printf("Encoding frame %u to %lu bytes", frameNumber, encFrame.length); */ if (frameNumber > 0 && (frameNumber % (10 * (int)frameRate)) == 0) { int elapsed = time(0) - startTime; if (elapsed > 0) { printf("Encoded %u seconds of video in %u seconds, %u fps\n", (int)(frameNumber / frameRate), elapsed, frameNumber / elapsed); } } } /* cleanup */ xvid_encore(xvidHandle, XVID_ENC_DESTROY, NULL, NULL); fclose(rawFile); fclose(mpeg4File); return(0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?