?? decoder.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 "avcdecoder.h"#define MAX_FILENAME_LEN 200#define SEPARATE_YUV_FILES 0#define COMBINED_YUV_FILE 1#define NALBUF_INITIAL_SIZE 4096#define NALBUF_BLOCK_SIZE 512#define READ_FRAME_BITS 1#define BYTE_STREAM 0#define RTP_STREAM 1typedef struct _videoFile_s { int enabled; int format; FILE *y; FILE *u; FILE *v; FILE *yuv;} videoFile_s;typedef struct _userParam_s { char *inFile; char *recoFile; int recoFormat; char *cumuFile; int cropFlag; int ecAlg;} userParam_s;typedef struct _byteStream_s { FILE *fn; /* Bitstream file pointer */ long bytesRead; /* The number of bytes read from the file */ unsigned char *bitbuf; /* Buffer for stream bits */ int bitbufLen; /* Size of the bit buffer in bytes */ int bitbufDataPos; int bitbufDataLen; /* Length of all the data in the bit buffer in bytes */ unsigned char *bitbufNalunit; /* Pointer to first NAL unit in the bitbuffer */ int bitbufNalunitLen; /* Length of the first NAL unit in the bit buffer in bytes, including variable size start code, nal head byte and the RBSP payload. It will help to find the RBSP length. */} byteStream_s;typedef struct _statOverall_s { long numBitsI; long numBitsP; long numIframes; long numPframes;} statOverall_s;/* * * usage: * * Parameters: * - * * Function: * Print decoder usage information. * * Returns: * - */static void usage(void){ fprintf(stderr,"Decoder parameters:\n"); fprintf(stderr," -i <bitstream filename> [(mandatory)]\n"); fprintf(stderr," [-reco <reconstruction filename>] [default none]\n"); fprintf(stderr," [-recoyuv <reconstruction filename>] [default none]\n"); fprintf(stderr," [-cumul file] Per total statistics [default none]\n"); fprintf(stderr," [-crop] [default no cropping]\n");#ifdef ERROR_CONCEALMENT fprintf(stderr," [-ecAlg] Error Concealment Algorithm [default TCON]\n"); fprintf(stderr," 0: Previous Frame Copy\n"); fprintf(stderr," 1: TCON\n");#endif}/* * * parseArg: * * Parameters: * argc Number of parameters * argv Parameter strings * param Structure where parameters will be stored * * Function: * Parse decoder parameters * * Returns: * 0 error * 1 ok * */static int parseArg(int argc, char **argv, userParam_s *param){ int i; param->inFile = NULL; param->recoFile = NULL; param->cumuFile = NULL; param->cropFlag = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-i") == 0) { if (++i == argc) { return 0; } param->inFile = argv[i]; } else if (strcmp(argv[i], "-reco") == 0) { if (++i == argc) { return 0; } param->recoFormat = SEPARATE_YUV_FILES; param->recoFile = argv[i]; } else if (strcmp(argv[i], "-recoyuv") == 0) { if (++i == argc) { return 0; } param->recoFormat = COMBINED_YUV_FILE; param->recoFile = argv[i]; } else if (strcmp(argv[i], "-cumul") == 0) { if (++i == argc) { return 0; } param->cumuFile = argv[i]; } else if (strcmp(argv[i], "-crop") == 0) { param->cropFlag = 1; } else if (strcmp(argv[i], "-ecAlg") == 0) { if (++i == argc) { return 0; } param->ecAlg = atoi(argv[i]); } else { return 0; } } if (param->inFile == NULL) { fprintf(stderr, "Source file required\n\n"); return 0; } return 1;}/* * * printSeqStat: * * Parameters: * seqStat Statistics object * qpIntra Intra quantization parameter * qpInter Inter quantization parameter * fp Destination stream * * Function: * Print sequence statistics * * Returns: * - * */static void printSeqStat(statOverall_s *seqStat, int qpIntra, int qpInter, FILE *fp){ long nFrames; nFrames = seqStat->numIframes + seqStat->numPframes; if (nFrames == 0) return; fprintf(fp, "%3ld %2d %2d %2.2f %2.2f %2.2f %5ld " "%2.2f %2.2f %2.2f %5ld " "%2.2f %2.2f %2.2f %5ld %.3f\n", nFrames, qpInter, qpIntra, 0.0, 0.0, 0.0, seqStat->numIframes != 0 ? seqStat->numBitsI/seqStat->numIframes : 0, 0.0, 0.0, 0.0, seqStat->numPframes != 0 ? seqStat->numBitsP/seqStat->numPframes : 0, 0.0, 0.0, 0.0, (seqStat->numBitsI + seqStat->numBitsP)/nFrames, (double)clock()/CLOCKS_PER_SEC/nFrames);}/* * * openFiles: * * Parameters: * param Parameters * recoFile Decoded sequence file * recoFlag If 1, dec. file opened * strByte Bitsream * * Function: * Open raw video files * * Returns: * - * */static void openFiles(userParam_s *param, videoFile_s *recoFile, byteStream_s *strByte){ char tmpName[MAX_FILENAME_LEN+1]; /* * Open reconstruction file if requested */ if (param->recoFile != NULL && strlen(param->recoFile)+2 > MAX_FILENAME_LEN) { fprintf(stderr, "Too long reconstruction file name\n"); exit(1); } recoFile->enabled = 0; if (param->recoFile != NULL) { switch (param->recoFormat) { case SEPARATE_YUV_FILES: sprintf(tmpName, "%s%s", param->recoFile, ".y"); if ((recoFile->y = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->recoFile, ".u"); if ((recoFile->u = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } sprintf(tmpName, "%s%s", param->recoFile, ".v"); if ((recoFile->v = fopen(tmpName, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", tmpName); exit(1); } break; case COMBINED_YUV_FILE: if ((recoFile->yuv = fopen(param->recoFile, "wb")) == NULL) { fprintf(stderr, "Cannot open reconstruction file \"%s\"\n", param->recoFile); exit(1); } break; default: fprintf(stderr, "Unknown reconstruction file format\n"); exit(1); } recoFile->enabled = 1; recoFile->format = param->recoFormat; } /* * open bitstream file */ if ((strByte->fn = fopen(param->inFile, "rb")) == NULL) { fprintf(stderr, "Cannot open input bitstream\n"); exit(1); } if ((strByte->bitbuf = malloc(NALBUF_INITIAL_SIZE)) == NULL) { fprintf(stderr, "Cannot allocate memory for bitstream\n"); exit(1); } strByte->bytesRead = 0; strByte->bitbufLen = NALBUF_INITIAL_SIZE; strByte->bitbufDataLen = 0; strByte->bitbufDataPos = 0; strByte->bitbufNalunitLen = 0;}/* * * closeFiles: * * Parameters: * recoFile Reconstruction file * recoFlag Rec. frames were written to file if true * str Bitsream * * Function: * Close raw video files * * Returns: * - * */static void closeFiles(videoFile_s *recoFile, byteStream_s *str){ if (recoFile->enabled) { switch (recoFile->format) { case SEPARATE_YUV_FILES: fclose(recoFile->y); fclose(recoFile->u); fclose(recoFile->v); break; case COMBINED_YUV_FILE: fclose(recoFile->yuv); } recoFile->enabled = 0; } fclose(str->fn); free(str->bitbuf);}/* * * writeFrame: * * Parameters: * buf Frame buffer * outFile Destination file * cropFlag True if cropping enabled * * Function: * Writes frame to the file * * Returns: * - * */static void writeFrame(avcdYUVbuffer_s *buf, videoFile_s *outFile, int cropFlag){ FILE *yFile, *uFile, *vFile; if (buf == NULL) return; switch (outFile->format) { case SEPARATE_YUV_FILES: yFile = outFile->y; uFile = outFile->u; vFile = outFile->v; break; case COMBINED_YUV_FILE: yFile = uFile = vFile = outFile->yuv; break; default: fprintf(stderr, "Unknown reconstruction file type\n"); exit(1); } if (!(cropFlag && (buf->cropLeftOff | buf->cropRightOff | buf->cropTopOff | buf->cropBottomOff) != 0)) { fwrite(buf->y, sizeof(unsigned char), buf->width*buf->height, yFile); fwrite(buf->u, sizeof(unsigned char), buf->width*buf->height/4, uFile); fwrite(buf->v, sizeof(unsigned char), buf->width*buf->height/4, vFile); } else { int cropTop, cropBottom, cropLeft, cropRight; int totalWidth; int cropWidth, cropHeight; unsigned char *imgPtr; int i; cropTop = 2*buf->cropTopOff; cropBottom = 2*buf->cropBottomOff; cropLeft = 2*buf->cropLeftOff; cropRight = 2*buf->cropRightOff; totalWidth = buf->width; cropWidth = totalWidth - cropLeft - cropRight; cropHeight = buf->height - cropTop - cropBottom; imgPtr = &((unsigned char *)buf->y)[cropTop*totalWidth + cropLeft]; for (i = 0; i < cropHeight; i++) fwrite(&imgPtr[i*totalWidth], sizeof(unsigned char), cropWidth, yFile); totalWidth = totalWidth/2; cropWidth = cropWidth/2; cropHeight = cropHeight/2; imgPtr = &((unsigned char *)buf->u)[cropTop/2*totalWidth + cropLeft/2]; for (i = 0; i < cropHeight; i++) fwrite(&imgPtr[i*totalWidth], sizeof(unsigned char), cropWidth, uFile); imgPtr = &((unsigned char *)buf->v)[cropTop/2*totalWidth + cropLeft/2]; for (i = 0; i < cropHeight; i++) fwrite(&imgPtr[i*totalWidth], sizeof(unsigned char), cropWidth, vFile); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -