📄 encoder.c
字号:
/*COPYRIGHT, LICENSE AND WARRANTY INFORMATIONThis software module has been originally developed by Nokia Corporation. Provided that a person, entity or a company willing to use the Software (hereinafter Licensee) comply with all the terms and conditions of this Statement and subject to the limitations set forth in this Statement Nokia grants to such Licensee a non-exclusive, sub-licensable, worldwide, limited license under copyrights owned by Nokia to use the Software for the sole purpose of creating, manufacturing, selling, marketing, or distributing (including the right to make modifications to the Software) a fully compliant decoder implementation (hereinafter "Decoder") of ITU-T Recommendation H.264 / ISO/IEC International Standard 14496-10 and an encoder implementation producing output that is decodable with the Decoder.Nokia retains the ownership of copyrights to the Software. There is no patent nor other intellectual property right of Nokia licensed under this Statement (except the copyright license above). Licensee hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if patent licenses are required, it is their responsibility to acquire the license before utilizing the Software.The license by Nokia is subject to that the Licensee grants to Nokia the non-exclusive, worldwide, royalty-free, perpetual and irrevocable covenant that the Licensee(s) shall not bring a suit before any court or administrative agency or otherwise assert a claim for infringement under the Licensee intellectual property rights that, but for a license, would be infringed by the Software against (a) Nokia or Nokia's Affiliate; or (b) other recipient of a license and covenant not to sue with respect to the Software from Nokia; or (c) contractor, customer or distributor of a party listed above in a or b, which suit or claim is related to the Software or use thereof.The Licensee(s) further agrees to grant a reciprocal license to Nokia (as granted by Nokia to the Licensee(s) on the modifications made by Licensee(s) to the Software. THE SOFTWARE IS PROVIDED "AS IS" AND THE ORIGINAL DEVELOPER DISCLAIMS ANY AND ALL WARRANTIES WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. THOSE INTENDING TO USE THE SOFTWARE ARE EXPRESSLY ADVISED THAT ITS USE MAY INFRINGE EXISTING PATENTS AND BE SUBJECT TO ROYALTY PAYMENTS TO PATENT OWNERS. ANYONE USING THE SOFTWARE ON THE BASIS OF THIS LICENSE AGREES TO OBTAIN THE NECESSARY PERMISSIONS FROM ANY AND ALL APPLICABLE PATENT OWNERS FOR SUCH USE.IN NO EVENT SHALL THE ORIGINAL DEVELOPER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.This copyright, license and warranty information notice must be retained in all copies and derivative works of the Software or substantial portions thereof.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <time.h>#include <limits.h>#include "avcencoder.h"long scdSceneCut();#define MAX_FILENAME_LEN 200#define SEPARATE_YUV_FILES 0#define COMBINED_YUV_FILE 1#define clip(min, max, val) (((val)<(min))? (min):(((val)>(max))? (max):(val)))#define MAX_FRM_NUM ((1 << 30) - 1)/* YUV raw video file structure */typedef struct _videoFile_s{ int format; FILE *y; FILE *u; FILE *v;} videoFile_s;/* Parameters from user (command line) */typedef struct _userParam_s{ char origFileName[256]; char outFileName[256]; char recoFileName[256]; char cumuFileName[256]; int seqFormat; int recoFormat; int startFrm; int numFrms; int frmSkip; int intraFreq; int idrFreq; int numNonref; int qpNonref; int qpIntra; int qpInter; int qpInter2; int q2Start; int ltrIdr; // IDR image will always become long term ref int ltrStart; int ltrFreq; char fScenecut;//Scenecut char fScenecutSei; int minIdrDistance; int Sumy, Sumuv; int PTqp; double BR, Bsize, bmax, bmin, *Buffer; int fInfo; int fSRC_Create;} userParam_s;/** Definition for command line parsing*//* Command flag and type definitions */#define CMD_FLAG 0#define CMD_INT 1#define CMD_STR 2/* Structure holds a command from command line */typedef struct _cmdEntry_s{ int flag; // flag = 1, if the command appears on the command line int type; // 0, integer, 1, string, 2, no data to follow char id[32]; // should be long enough int defaultData; // valid only if type != CMD_STR void *data; struct _cmdEntry_s *next;} cmdEntry_s;typedef struct _cmdBuf_s{ int numCmds; cmdEntry_s *head; cmdEntry_s *current;} cmdBuf_s;/** Static function prototypes*/static void usage(void);static int parseModes(char *modeString);static void printSeqStat(avceEncoder_t *encoder, int qpIntra, int qpInter, int frameRateTimes1000, int numSkippedFrames, FILE *fp);static void dumpStatistics(avceEncoder_t *encoder, int frameRateTimes1000, int numSkippedFrames);static void allocOrigFrame(avceYUVbuffer_s *buf, int width, int height);static void freeOrigFrame(avceYUVbuffer_s *buf);static int openVideoFiles(userParam_s *param, videoFile_s *origFile, videoFile_s *recoFile, FILE **stream);static void closeFiles(videoFile_s *origFile, videoFile_s *recoFile, int recoFlag, FILE *stream);static int readFrame(avceYUVbuffer_s *buf, int width, int height, videoFile_s *inFile, int frameIdx);static void writeFrame(avceYUVbuffer_s *buf, avceOpenParams_s *seqParam, videoFile_s *outFile, int frameIdx);/* * usage: * * Parameters: * - * * Function: * Print encoder usage information. * * Returns: * - */static void usage(void){ fprintf(stdout, "Encoder arguments:\n" " [-h] To get this help screen. \n" " -in <file name> Input Y,U,V in separate files [default none]\n" " -inyuv <file name> Input Y,U,V in one file [default none]\n" " -out <file name> Output bitstream name [default none]\n" " [-level <value>] AVC level times 10 [default 20]\n" " [-width <value>] Picture width in pixels [default 176]\n" " [-height <value>] Picture height in pixels [default 144]\n" " [-qcif] Set picture size 176x144\n" " [-cif] Set picture size 352x288\n" " [-start <value>] First frame number [default 0]\n" " [-skip <value>] Number of skipped frames [default 2]\n" " target frame rate = origfps/(skip+1)\n" " [-frames <value>] Number of frames to be encoded [default 2^31-1]\n" " [-origfps <value>] Original frame rate [default 30]\n" " [-IpP <value>] Insert non-reference frames [default 0]\n" " between reference frames.\n" " 0, no non-reference frame.\n" " <= 8, number of non-ref frames.\n" " [-qNonref <value>] qp of non-reference frames. [default q]\n" " Same as ""q"", if not provided.\n" " [-tuneIntra <value>] Tune intra frame quality. [default 256]\n" " [-tuneInter <value>] Tune inter frame quality. [default 256]\n" " [-tuneNonref <value>] Tune non-reference frame quality. [default 256]\n" " For the 3 switches above:\n" " Take effect only when ""-rdo 1"".\n" " > 1024, smaller frame size.\n" " < 1024, higher quality.\n" " [-intraFreq <value>] How often intra frame is inserted [default 0]\n" " 0, only first frame is intra.\n" " [-idrFreq <value>] How often IDR frame is inserted [default 0]\n" " 0, only first frame is IDR.\n" " If -intraFreq is defined, idrFreq must\n" " be larger than or equal to intraFreq.\n" " First frame must be intra and IDR.\n" " [-qintra <value>] Luma QP for I frame [default 32]\n" " [-q <value>] Luma QP for P frames [default 32]\n" " [-q2Start <value>] Use q2 after q2Start frames [default 2^31-1]\n" " Index to frames actually encoded.\n" " Not to the source video clip.\n" " [-q2 <value>] Luma QP for second part of clip. [default q]\n" " Same as ""q"", if not provided.\n" " [-cumul <file name>] Write statistics to file [default none]\n" " [-reco <file name>] Output Y,U,V in separate files [default none]\n" " [-recoyuv <file name>] Output Y,U,V in one file [default none]\n" " [-scIntra <value>] Encode a scene cut image as an [default 0]\n" " intra frame. This scene cut\n" " information is from coding results.\n" " 0, no effect.\n" " 1, convert only all MBs are intra.\n" " 2, more aggressive conversion.\n" " [-ltrIdr] IDR used as a long term ref frame. [default disabled]\n" " [-ltrStart <value>] First frame to be used as [default 0]\n" " a long term reference frame.\n" " [-ltrFreq <value>] Use a reconstructed frame as [default 0]\n" " a long term reference frame for\n" " every ""ltrFreq"" frames\n" " 0, no long term reference frame.\n" " Maximally 1 long term ref frame.\n" " [-rframes <value>] Number of reference frames. [default 1]\n" " 0, all frames are coded intra.\n" " [-maxFrameNum <value>] Specify log2_max_frame_num_minus4 [default 0]\n" " [-modes <mode string>] Block sizes to be used. [default 1111111]\n" " 0, corresponding mode is disbaled,\n" " 1, corresponding mode is enabled.\n" " Order of the modes is:\n" " 16x16 16x8 8x16 8x8 8x4 4x8 4x4\n" " [-range <value>] Max search range in ME [default 16]\n" " motion estimation.\n" " [-qindex <value>] Chroma QP index [-12,12] [default 0]\n" " Adjustment of chroma QP relative to luma QP\n" " [-constipred] Enable constrained intra pred, [default disabed]\n" " i.e. no intraprediction from inter macroblocks.\n" " [-filtermode <value>] Loopfilter mode [default 0]\n" " 0, enabled\n" " 1, disabled\n" " 2, disabled on slice boundaries\n" " [-alpha <value>] Loopfilter alpha offset [-6,6] [default 0]\n" " [-beta <value>] Loopfilter beta offset [-6,6] [default 0]\n" " [-mfield] Show motion field in [default none]\n" " recontruction frames.\n" " [-sgmType <value>] Slice group map (SGM) type [0, 6] [default 0]\n" " [-sgmCount <value>] # of slices groups in a frame [default 1]\n" " [-sgmParams <v0> <...>] SGM parameters, up to 8 values\n" " Type 0, run lengths,\n" " Type 2, (UpperLeft, lowerRight) pairs,\n" " Type 3 4 5, direction and change rate,\n" " [-mbsperslice <value>] Number of macroblocks per slice, [default 0]\n" " 0 means one slice\n" " [-bytesperslice <value>] Number of bytes per slice, [default 0]\n" " 0 means one slice\n" " [-br <value>] Bit rate of compressed bitstream [default 0]\n" " 0, disable BRC, qintra & q are used,\n" " nonzero, enable BRC at this bit rate,\n" " qintra & q are reference values,\n" " [-brcBufSize <value>] Size of encoder virtual buffer [default max.]\n" " verifier in bytes\n" " [-brcQPStart <value>] First Frame QP used by Rate Control[default 0]\n" " If not specified encoder estimates \n" " according to bitrate \n" " [-brcFrameSkipsEnabled <value>] Rate Control algorithm [default 1]\n" " skips frames to avoid buffer overflow\n" " 0, Frame Skipping is not allowed\n" " 1, Frame Skipping is allowed\n" " 2, Advanced Frame Skipping algorithm\n" " [-brcIgnoreIDRBits <value>] Rate Control algorithm [default 0]\n" " does not take into account intraframe bits\n" " 0: Not Ignored\n" " 1: Only Ignored in low delay\n" " 2: Forced to Ignore\n" " [-brcdisableMBLevel] Disable MB Level Rate Control\n [default enabled]\n" " [-brcuseSEI] Put timing and buffer related, [default disabled]\n" " messages to the bitstream\n" " [-prof <value>] Encoder quality setting [default 0]\n" " 0, favor coding efficiency\n" " 1, favor encoding speed\n"///// LOW_COMPLEX_PROF3 " 2, more favor encoding speed\n"/////#ifndef DISABLE_RDO " [-rdo <value>] Rate distortion optimization [default 1]\n" " 0, disable RDO\n" " 1, enable RDO\n"#endif " [-crop <L> <R> <T> <B>] Output frame croppping. [default all 0]\n" " <L>, frame_crop left offset.\n" " <R>, frame_crop right offset.\n" " <T>, frame_crop top offset.\n" " <B>, frame_crop bottom offset.\n" " Odd values will be changed to even.\n" " [-scut] Perform Scene Cut Detection [default disabled].\n" " [-sceneInfo] Generate the scene info SEI messages.\n" " [-RIR <value>] Enables Random Intra Refresh [default 0].\n" " #I-MBs put randomly should be provided\n" " Actual number could be less than the provided\n" " [-PLR <value>] Packet loss rate [default 0].\n" " It is used with AIR Intra Refresh algorithm\n" " [-AIR] Enables Advanced Intra Refresh [default disabled].\n" " [-info] Printout Info.\n" );}/* * parseModes: * * Parameters: * modeString String containing '1' for enabled motion mode * and '0' bit for disabled motion mode * * Function: * Convert mode string to integer number * * Returns: * Integer containing mode bits */static int parseModes(char *modeString){ int modes; int i; if (strlen(modeString) > 7) return -1; modes = 0; for (i = 0; i < (int)strlen(modeString); i++) { if (modeString[i] == '1') modes |= (1 << i); else if (modeString[i] != '0') return -1; } return modes;}/* * insertCmd: * * Parameters: * cmdEntry Command structure * type Command type (integer or string) * defaultData Default value if the command does not appear * cmdId Command string * dataBuf Command parameter * * Function: * Put a command in the command buffer structure. * * Returns: * - */static void insertCmd(cmdBuf_s *cmdBuf, int type, int defaultData, char *cmdId, void *dataBuf){ cmdEntry_s *newEntry; newEntry = (cmdEntry_s *) malloc(sizeof(cmdEntry_s)); newEntry->type = type; strcpy(newEntry->id, cmdId); newEntry->data = dataBuf; if (type != CMD_STR) * ((int *) newEntry->data) = defaultData; cmdBuf->current->next = newEntry; cmdBuf->current = newEntry; cmdBuf->numCmds ++;}/* * getCmdBuf: * * Parameters: * up Parameter from user * sp Parameter from user to be passed to AVC decoder * * Function: * Allocate and initialize the command buffer, which is used in parsing * the input commands. * The buffer is a link list so that the user does not need to worry * about how the buffer entries are maintained. Each entry in the list * contains command ID, type, command data buffer, and default value. * * Returns: * command buffer allocated. */static cmdBuf_s *getCmdBuf(userParam_s *up, avceOpenParams_s *sp){ int i; cmdBuf_s *cmdBuf; if ((cmdBuf = malloc(sizeof(cmdBuf_s))) == 0) return 0; cmdBuf->numCmds = 0; // we have an empty slot cmdBuf->head = (cmdEntry_s *) malloc(sizeof(cmdEntry_s)); strcpy(cmdBuf->head->id, "xxHeadxx"); cmdBuf->current = cmdBuf->head; cmdBuf->current->next = 0; // a string should follow the command insertCmd(cmdBuf, CMD_STR, 0, "-cumul", up->cumuFileName); insertCmd(cmdBuf, CMD_STR, 0, "-out", up->outFileName); insertCmd(cmdBuf, CMD_FLAG, 0, "-scut", &up->fScenecut); // an integer should follow the command insertCmd(cmdBuf, CMD_INT, 0, "-start", & up->startFrm); insertCmd(cmdBuf, CMD_INT, 2, "-skip", & up->frmSkip); insertCmd(cmdBuf, CMD_INT, INT_MAX, "-frames", & up->numFrms); insertCmd(cmdBuf, CMD_INT, 0, "-IpP", & up->numNonref); insertCmd(cmdBuf, CMD_INT, 32, "-qintra", & up->qpIntra); insertCmd(cmdBuf, CMD_INT, 32, "-q", & up->qpInter); insertCmd(cmdBuf, CMD_INT, -1, "-qNonref", & up->qpNonref); insertCmd(cmdBuf, CMD_INT, 0, "-intraFreq", & up->intraFreq); insertCmd(cmdBuf, CMD_INT, 0, "-idrFreq", & up->idrFreq); insertCmd(cmdBuf, CMD_INT, INT_MAX, "-q2Start", & up->q2Start); insertCmd(cmdBuf, CMD_INT, -1, "-q2", & up->qpInter2); insertCmd(cmdBuf, CMD_FLAG, 0, "-ltrIdr", & up->ltrIdr); insertCmd(cmdBuf, CMD_INT, 0, "-ltrStart", & up->ltrStart); insertCmd(cmdBuf, CMD_INT, 0, "-ltrFreq", & up->ltrFreq); insertCmd(cmdBuf, CMD_FLAG, 0, "-sceneInfo", & up->fScenecutSei); insertCmd(cmdBuf, CMD_INT, 0, "-idrAdap", & up->minIdrDistance); insertCmd(cmdBuf, CMD_INT, 176, "-width", & sp->picWidth); insertCmd(cmdBuf, CMD_INT, 144, "-height", & sp->picHeight);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -