📄 encoder.c
字号:
fprintf(stderr, "Output bitstream file required\n\n"); return 0; } // plr adjustment if (seqParam->plr < 0) seqParam->plr = 0; // numReorderFrames indicates the maximum number of frames that precede // any frame in the sequence in decoding order, but follow it in output order if (param->numNonref == 0) seqParam->numReorderFrames = 0; else seqParam->numReorderFrames = 1; if (seqParam->sIntraRefresh != 0) { if (seqParam->nRandomIntraRefresh != 0) { fprintf(stderr, "Only one of the Intra Refresh algorithm can be enabled.\n"); return 0; } if (seqParam->plr == 0) { fprintf(stderr, "Warning: Intra Refresh is enabled, but the packet loss rate is 0!\n"); } } else { if (seqParam->plr != 0) { fprintf(stderr, "Warning: Advanced Intra Refresh is NOT enabled, packet loss rate information is not used.\n"); return 0; } } return 1;}void deleteList(cmdEntry_s *list){ cmdEntry_s *next; if (list) do { next = list->next; free(list); list = next; } while (list);}/* * processCommands: * * Parameters: * argc Number of the input strings * argv Array contains the input strings * param User parameters, only used in this module * seqParam Coding parameters, used in this module & encoder * * Function: * Process the input commands * * Returns: * - */static int processCommands(int argc, char **argv, userParam_s *param, avceOpenParams_s *seqParam){ FILE *cfgFile; int i, j; int argcNew; int correctArgs; char *argvNew[MAX_CFG_COMMANDS]; cmdBuf_s *cmdBuf; // preprocess the arguments, there could be a config file cfgFile = 0; argcNew = argc; for (i = 1; i < argc; i ++) { if (strcmp(argv[i], "-cfg") == 0) { if (i == argc - 1) return 0; if ((cfgFile = fopen(argv[i + 1], "rt")) == 0) return 0; // copy the commands, except config file switches, to the new buffer argcNew = i; for (j = 0; j < argcNew; j ++) { argvNew[j] = (char *) malloc(strlen(argv[j]) + 1); strcpy(argvNew[j], argv[j]); } // read the config file argcNew += readConfigFile(cfgFile, argvNew + argcNew, MAX_CFG_COMMANDS - argcNew); // copy the remaining commands from the command line to same buffer for (j = i + 2; j < argc; j ++) { argvNew[argcNew] = (char *) malloc(strlen(argv[j]) + 1); strcpy(argvNew[argcNew ++], argv[j]); } for (j = argcNew; j < MAX_CFG_COMMANDS; j ++) argvNew[j] = 0; break; } } // the default values of all other parameters are set in fillCommandArr if ((cmdBuf = getCmdBuf(param, seqParam)) != 0) { // remove the buffer and close the config if (cfgFile) { // buffer was allocated if the cfgFile is open correctArgs = parseArg(cmdBuf, argcNew, argvNew, param, seqParam); for (i = 0; i < argcNew; i ++) free(argvNew[i]); fclose(cfgFile); } else correctArgs = parseArg(cmdBuf, argc, argv, param, seqParam); deleteList(cmdBuf->head); free(cmdBuf); if (correctArgs) return 1; } // it comes to here only if somthing is wrong usage(); exit(1);}/* * printSeqStat: * * Parameters: * encoder Encoder object * qpIntra Intra quantization parameter * qpInter Inter quantization parameter * fp Destination stream * * Function: * Print one line of sequence statistics * * Returns: * - */static void printSeqStat(avceEncoder_t *encoder, int qpIntra, int qpInter, int frameRateTimes1000, int numSkippedFrames, FILE *fp){ avceStatistics_s intraStat; avceStatistics_s interStat; avceStatistics_s seqStat; int nInterFrames; avceGetIntraStat(encoder, &intraStat); avceGetInterStat(encoder, &interStat); avceGetSeqStat(encoder, &seqStat); nInterFrames = interStat.nFrames ? interStat.nFrames : 1; fprintf(fp, "%3d %2d %2d %2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d %.3f %.3f\n", seqStat.nFrames, qpInter, qpIntra, intraStat.psnrY/intraStat.nFrames, intraStat.psnrU/intraStat.nFrames, intraStat.psnrV/intraStat.nFrames, intraStat.bits/intraStat.nFrames, interStat.psnrY/nInterFrames, interStat.psnrU/nInterFrames, interStat.psnrV/nInterFrames, interStat.bits/nInterFrames, seqStat.psnrY/seqStat.nFrames, seqStat.psnrU/seqStat.nFrames, seqStat.psnrV/seqStat.nFrames, seqStat.bits/seqStat.nFrames, 1.0*(interStat.bits+intraStat.bits)/(seqStat.nFrames+numSkippedFrames)*frameRateTimes1000/1000/1000, (double)clock()/CLOCKS_PER_SEC/seqStat.nFrames);}/* * dumpStatistics: * * Parameters: * encoder Encoder object * frameRateTimes1000 Target frame rate times 1000 * numSkippedFrames The number of skipped frames * * Function: * Print more detailed sequence statistics * * Returns: * - */static void dumpStatistics(avceEncoder_t *encoder, int frameRateTimes1000, int numSkippedFrames){ avceStatistics_s intraStat; avceStatistics_s interStat; avceStatistics_s seqStat; /* print a brief report */ avceGetIntraStat(encoder, &intraStat); avceGetInterStat(encoder, &interStat); avceGetSeqStat(encoder, &seqStat); printf("Total frames being encoded: %d\nI: %d, P: %d\n", seqStat.nFrames, intraStat.nFrames, interStat.nFrames); printf("Skipped frames: %d\n", numSkippedFrames); printf("Total bits in the stream: %d\n", seqStat.bits); printf("Bits in all NAL headers: %d\n", avceGetBitsNAL(encoder)); printf("Bits in Sequence Parameter Set: %d\n", avceGetBitsSPS(encoder)); printf("Bits in Picture Parameter Set: %d\n", avceGetBitsPPS(encoder)); printf("I-frame bits: %d, P-frame bits: %d\n", intraStat.bits, interStat.bits); if (interStat.nFrames > 0) { printf("P-frame bit rate: %d bits/second\n", (int) ((interStat.bits * (float)frameRateTimes1000/1000)/interStat.nFrames + 0.5f)); printf("Overall bit rate: %d bits/second\n", (int) (((interStat.bits + intraStat.bits) * (float)frameRateTimes1000/1000)/(interStat.nFrames+intraStat.nFrames+numSkippedFrames) + 0.5f)); } printf("Average PSNR: %5.2f\nI: %5.2f, P: %5.2f\n", seqStat.nFrames != 0? seqStat.psnrY / seqStat.nFrames : 9999, intraStat.nFrames != 0? intraStat.psnrY / intraStat.nFrames : 9999, interStat.nFrames != 0? interStat.psnrY / interStat.nFrames : 9999);}/* * allocOrigFrame: * * Parameters: * buf Frame buffer struct * width Frame width * height Frame height * * Function: * Allocate memory for original frame * * Returns: * - * */static void allocOrigFrame(avceYUVbuffer_s *buf, int width, int height){ int frmSize = width*height; int frmSizeC = width/2*height/2; if ((buf->y = malloc(frmSize*sizeof(unsigned char))) == NULL) { fprintf(stderr, "Cannot allocate orig frame memory\n"); exit(1); } if ((buf->u = malloc(frmSizeC*sizeof(unsigned char))) == NULL) { fprintf(stderr, "Cannot allocate orig frame memory\n"); exit(1); } if ((buf->v = malloc(frmSizeC*sizeof(unsigned char))) == NULL) { fprintf(stderr, "Cannot allocate orig frame memory\n"); exit(1); }}/* * freeOrigFrame: * * Parameters: * buf Frame buffer struct * * Function: * Free memory of original frame * * Returns: * - * */static void freeOrigFrame(avceYUVbuffer_s *buf){ free(buf->y); free(buf->u); free(buf->v);}/* * openVideoFiles: * * Parameters: * param Parameters * origFile Source file * recoFile Reconstruction file * stream bitsream file * * Function: * Open raw video files * * Returns: * 1 if reconstructed frames are written to file(s), 0 otherwise * */static int openVideoFiles(userParam_s *param, videoFile_s *origFile, videoFile_s *recoFile, FILE **stream){ char tmpName[MAX_FILENAME_LEN+1]; int writeReco = 0; /* * Open source sequence file */ if ((strlen(param->origFileName) != 0) && strlen(param->origFileName)+2 > MAX_FILENAME_LEN) { fprintf(stderr, "Too long input file name\n"); exit(1); } if ((strlen(param->recoFileName) != 0) && strlen(param->recoFileName)+2 > MAX_FILENAME_LEN) { fprintf(stderr, "Too long reconstruction file name\n"); exit(1); } switch (param->seqFormat) { case SEPARATE_YUV_FILES: sprintf(tmpName, "%s%s", param->origFileName, ".y"); if ((origFile->y = fopen(tmpName, "rb")) == NULL) { fprintf(stderr, "Input file \"%s\" not found\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->origFileName, ".u"); if ((origFile->u = fopen(tmpName, "rb")) == NULL) { fprintf(stderr, "Input file \"%s\" not found\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->origFileName, ".v"); if ((origFile->v = fopen(tmpName, "rb")) == NULL) { fprintf(stderr, "Input file \"%s\" not found\n", tmpName); exit(1); } break; case COMBINED_YUV_FILE: if ((origFile->y = fopen(param->origFileName, "rb")) == NULL) { fprintf(stderr, "Input file \"%s\" not found\n", param->origFileName); exit(1); } origFile->u = origFile->v = origFile->y; break; } origFile->format = param->seqFormat; /* * Open reconstruction file if requested */ if (strlen(param->recoFileName) != 0) { switch (param->recoFormat) { case SEPARATE_YUV_FILES: sprintf(tmpName, "%s%s", param->recoFileName, ".y"); if ((recoFile->y = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->recoFileName, ".u"); if ((recoFile->u = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->recoFileName, ".v"); if ((recoFile->v = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } recoFile->format = SEPARATE_YUV_FILES; break; case COMBINED_YUV_FILE: if ((recoFile->y = fopen(param->recoFileName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", param->recoFileName); exit(1); } recoFile->u = recoFile->v = recoFile->y; recoFile->format = COMBINED_YUV_FILE; break; } writeReco = 1; } if ((*stream = fopen(param->outFileName, "wb")) == NULL) { fprintf(stderr, "Cannot open output bitstream\n"); exit(1); } return writeReco;}/* * closeFiles: * * Parameters: * origFile Source file * recoFile Reconstruction file * recoFlag Rec. frames were written to file if true * stream bitsream file * * Function: * Close raw video files * * Returns: * 1 if reconstructed frames are written to file(s), 0 otherwise * */static void closeFiles(videoFile_s *origFile, videoFile_s *recoFile, int recoFlag, FILE *stream){ fclose(origFile->y); if (origFile->format == SEPARATE_YUV_FILES) { fclose(origFile->u); fclose(origFile->v); } // otherwise, u/v are the same file as y if it is COMBINED_YUV_FILE if (recoFlag) { fclose(recoFile->y); if (recoFile->format == SEPARATE_YUV_FILES) { fclose(recoFile->u); fclose(recoFile->v); } } fclose(stream);}/* * readFrame: * * Parameters: * buf Frame buffer * width Frame luma width * height Frame luma height * inFile Source file * * Function: * Read frame from file * * Returns: * 1 for success * 0 for failure * */static int readFrame(avceYUVbuffer_s *buf, int width, int height, videoFile_s *inFile, int frameIdx){ unsigned int nPixels = width*height; switch (inFile->format) { case SEPARATE_YUV_FILES: if (fseek(inFile->y, frameIdx * nPixels, SEEK_SET) != 0) return 0; if (fseek(inFile->u, frameIdx * nPixels/4, SEEK_SET) != 0) return 0; if (fseek(inFile->v, frameIdx * nPixels/4, SEEK_SET) != 0) return 0; break; case COMBINED_YUV_FILE: if (fseek(inFile->y, (frameIdx * nPixels * 3)/2, SEEK_SET) != 0) return 0; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -