DecTestBench.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
10c1bc742181ded4930842b46e9507372f0b1b963James Dong/* 20c1bc742181ded4930842b46e9507372f0b1b963James Dong * Copyright (C) 2009 The Android Open Source Project 30c1bc742181ded4930842b46e9507372f0b1b963James Dong * 40c1bc742181ded4930842b46e9507372f0b1b963James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 50c1bc742181ded4930842b46e9507372f0b1b963James Dong * you may not use this file except in compliance with the License. 60c1bc742181ded4930842b46e9507372f0b1b963James Dong * You may obtain a copy of the License at 70c1bc742181ded4930842b46e9507372f0b1b963James Dong * 80c1bc742181ded4930842b46e9507372f0b1b963James Dong * http://www.apache.org/licenses/LICENSE-2.0 90c1bc742181ded4930842b46e9507372f0b1b963James Dong * 100c1bc742181ded4930842b46e9507372f0b1b963James Dong * Unless required by applicable law or agreed to in writing, software 110c1bc742181ded4930842b46e9507372f0b1b963James Dong * distributed under the License is distributed on an "AS IS" BASIS, 120c1bc742181ded4930842b46e9507372f0b1b963James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c1bc742181ded4930842b46e9507372f0b1b963James Dong * See the License for the specific language governing permissions and 140c1bc742181ded4930842b46e9507372f0b1b963James Dong * limitations under the License. 150c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 160c1bc742181ded4930842b46e9507372f0b1b963James Dong 170c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "H264SwDecApi.h" 180c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <stdio.h> 190c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <stdlib.h> 200c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <string.h> 210c1bc742181ded4930842b46e9507372f0b1b963James Dong 220c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 230c1bc742181ded4930842b46e9507372f0b1b963James Dong Module defines 240c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 250c1bc742181ded4930842b46e9507372f0b1b963James Dong 260c1bc742181ded4930842b46e9507372f0b1b963James Dong/* CHECK_MEMORY_USAGE prints and sums the memory allocated in calls to 270c1bc742181ded4930842b46e9507372f0b1b963James Dong * H264SwDecMalloc() */ 280c1bc742181ded4930842b46e9507372f0b1b963James Dong/* #define CHECK_MEMORY_USAGE */ 290c1bc742181ded4930842b46e9507372f0b1b963James Dong 300c1bc742181ded4930842b46e9507372f0b1b963James Dong/* _NO_OUT disables output file writing */ 310c1bc742181ded4930842b46e9507372f0b1b963James Dong/* #define _NO_OUT */ 320c1bc742181ded4930842b46e9507372f0b1b963James Dong 330c1bc742181ded4930842b46e9507372f0b1b963James Dong/* Debug prints */ 340c1bc742181ded4930842b46e9507372f0b1b963James Dong#define DEBUG(argv) printf argv 350c1bc742181ded4930842b46e9507372f0b1b963James Dong 360c1bc742181ded4930842b46e9507372f0b1b963James Dong/* CVS tag name for identification */ 370c1bc742181ded4930842b46e9507372f0b1b963James Dongconst char tagName[256] = "$Name: FIRST_ANDROID_COPYRIGHT $"; 380c1bc742181ded4930842b46e9507372f0b1b963James Dong 390c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid WriteOutput(char *filename, u8 *data, u32 picSize); 400c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 NextPacket(u8 **pStrm); 410c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 CropPicture(u8 *pOutImage, u8 *pInImage, 420c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 picWidth, u32 picHeight, CropParams *pCropParams); 430c1bc742181ded4930842b46e9507372f0b1b963James Dong 440c1bc742181ded4930842b46e9507372f0b1b963James Dong/* Global variables for stream handling */ 450c1bc742181ded4930842b46e9507372f0b1b963James Dongu8 *streamStop = NULL; 460c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 packetize = 0; 470c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 nalUnitStream = 0; 480c1bc742181ded4930842b46e9507372f0b1b963James DongFILE *foutput = NULL; 490c1bc742181ded4930842b46e9507372f0b1b963James Dong 500c1bc742181ded4930842b46e9507372f0b1b963James Dong#ifdef SOC_DESIGNER 510c1bc742181ded4930842b46e9507372f0b1b963James Dong 520c1bc742181ded4930842b46e9507372f0b1b963James Dong// Initialisation function defined in InitCache.s 530c1bc742181ded4930842b46e9507372f0b1b963James Dongextern void cache_init(void); 540c1bc742181ded4930842b46e9507372f0b1b963James Dong 550c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 560c1bc742181ded4930842b46e9507372f0b1b963James Dong 570c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: $Sub$$main 580c1bc742181ded4930842b46e9507372f0b1b963James Dong 590c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 600c1bc742181ded4930842b46e9507372f0b1b963James Dong This function is called at the end of the C library initialisation and 610c1bc742181ded4930842b46e9507372f0b1b963James Dong before main. Its purpose is to do any further initialisation before the 620c1bc742181ded4930842b46e9507372f0b1b963James Dong application start. 630c1bc742181ded4930842b46e9507372f0b1b963James Dong 640c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 650c1bc742181ded4930842b46e9507372f0b1b963James Dongint $Sub$$main(char argc, char * argv[]) 660c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 670c1bc742181ded4930842b46e9507372f0b1b963James Dong cache_init(); // does some extra setup work setting up caches 680c1bc742181ded4930842b46e9507372f0b1b963James Dong return $Super$$main(argc, argv); // calls the original function 690c1bc742181ded4930842b46e9507372f0b1b963James Dong} 700c1bc742181ded4930842b46e9507372f0b1b963James Dong#endif 710c1bc742181ded4930842b46e9507372f0b1b963James Dong 720c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 730c1bc742181ded4930842b46e9507372f0b1b963James Dong 740c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: main 750c1bc742181ded4930842b46e9507372f0b1b963James Dong 760c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 770c1bc742181ded4930842b46e9507372f0b1b963James Dong main function of decoder testbench. Provides command line interface 780c1bc742181ded4930842b46e9507372f0b1b963James Dong with file I/O for H.264 decoder. Prints out the usage information 790c1bc742181ded4930842b46e9507372f0b1b963James Dong when executed without arguments. 800c1bc742181ded4930842b46e9507372f0b1b963James Dong 810c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 820c1bc742181ded4930842b46e9507372f0b1b963James Dong 830c1bc742181ded4930842b46e9507372f0b1b963James Dongint main(int argc, char **argv) 840c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 850c1bc742181ded4930842b46e9507372f0b1b963James Dong 860c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 i, tmp; 870c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 maxNumPics = 0; 880c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 *byteStrmStart; 890c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 *imageData; 900c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 *tmpImage = NULL; 910c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 strmLen; 920c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 picSize; 930c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecInst decInst; 940c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecRet ret; 950c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecInput decInput; 960c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecOutput decOutput; 970c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecPicture decPicture; 980c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecInfo decInfo; 990c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecApiVersion decVer; 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 picDecodeNumber; 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 picDisplayNumber; 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 numErrors = 0; 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 cropDisplay = 0; 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 disableOutputReordering = 0; 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong FILE *finput; 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong char outFileName[256] = ""; 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Print API version number */ 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong decVer = H264SwDecGetAPIVersion(); 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("H.264 Decoder API v%d.%d\n", decVer.major, decVer.minor)); 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Print tag name if '-T' argument present */ 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( argc > 1 && strcmp(argv[1], "-T") == 0 ) 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("%s\n", tagName)); 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong return 0; 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Check that enough command line arguments given, if not -> print usage 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong * information out */ 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong if (argc < 2) 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(( 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file.h264\n", 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong argv[0])); 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-Nn forces decoding to stop after n pictures\n")); 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong#if defined(_NO_OUT) 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-Ooutfile output writing disabled at compile time\n")); 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong#else 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-Ooutfile write output to \"outfile\" (default out_wxxxhyyy.yuv)\n")); 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-Onone does not write output\n")); 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong#endif 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-P packet-by-packet mode\n")); 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-U NAL unit stream mode\n")); 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-C display cropped image (default decoded image)\n")); 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-R disable DPB output reordering\n")); 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\t-T to print tag name and exit\n")); 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong return 0; 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong /* read command line arguments */ 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = 1; i < (u32)(argc-1); i++) 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( strncmp(argv[i], "-N", 2) == 0 ) 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong maxNumPics = (u32)atoi(argv[i]+2); 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ( strncmp(argv[i], "-O", 2) == 0 ) 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong strcpy(outFileName, argv[i]+2); 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ( strcmp(argv[i], "-P") == 0 ) 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong packetize = 1; 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ( strcmp(argv[i], "-U") == 0 ) 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong nalUnitStream = 1; 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1620c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ( strcmp(argv[i], "-C") == 0 ) 1630c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1640c1bc742181ded4930842b46e9507372f0b1b963James Dong cropDisplay = 1; 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ( strcmp(argv[i], "-R") == 0 ) 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1680c1bc742181ded4930842b46e9507372f0b1b963James Dong disableOutputReordering = 1; 1690c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1700c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1710c1bc742181ded4930842b46e9507372f0b1b963James Dong 1720c1bc742181ded4930842b46e9507372f0b1b963James Dong /* open input file for reading, file name given by user. If file open 1730c1bc742181ded4930842b46e9507372f0b1b963James Dong * fails -> exit */ 1740c1bc742181ded4930842b46e9507372f0b1b963James Dong finput = fopen(argv[argc-1],"rb"); 1750c1bc742181ded4930842b46e9507372f0b1b963James Dong if (finput == NULL) 1760c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1770c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("UNABLE TO OPEN INPUT FILE\n")); 1780c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 1790c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1800c1bc742181ded4930842b46e9507372f0b1b963James Dong 1810c1bc742181ded4930842b46e9507372f0b1b963James Dong /* check size of the input file -> length of the stream in bytes */ 1820c1bc742181ded4930842b46e9507372f0b1b963James Dong fseek(finput,0L,SEEK_END); 1830c1bc742181ded4930842b46e9507372f0b1b963James Dong strmLen = (u32)ftell(finput); 1840c1bc742181ded4930842b46e9507372f0b1b963James Dong rewind(finput); 1850c1bc742181ded4930842b46e9507372f0b1b963James Dong 1860c1bc742181ded4930842b46e9507372f0b1b963James Dong /* allocate memory for stream buffer. if unsuccessful -> exit */ 1870c1bc742181ded4930842b46e9507372f0b1b963James Dong byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen); 1880c1bc742181ded4930842b46e9507372f0b1b963James Dong if (byteStrmStart == NULL) 1890c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1900c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("UNABLE TO ALLOCATE MEMORY\n")); 1910c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 1920c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1930c1bc742181ded4930842b46e9507372f0b1b963James Dong 1940c1bc742181ded4930842b46e9507372f0b1b963James Dong /* read input stream from file to buffer and close input file */ 1950c1bc742181ded4930842b46e9507372f0b1b963James Dong fread(byteStrmStart, sizeof(u8), strmLen, finput); 1960c1bc742181ded4930842b46e9507372f0b1b963James Dong fclose(finput); 1970c1bc742181ded4930842b46e9507372f0b1b963James Dong 1980c1bc742181ded4930842b46e9507372f0b1b963James Dong /* initialize decoder. If unsuccessful -> exit */ 1990c1bc742181ded4930842b46e9507372f0b1b963James Dong ret = H264SwDecInit(&decInst, disableOutputReordering); 2000c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret != H264SWDEC_OK) 2010c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2020c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("DECODER INITIALIZATION FAILED\n")); 2030c1bc742181ded4930842b46e9507372f0b1b963James Dong free(byteStrmStart); 2040c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 2050c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2060c1bc742181ded4930842b46e9507372f0b1b963James Dong 2070c1bc742181ded4930842b46e9507372f0b1b963James Dong /* initialize H264SwDecDecode() input structure */ 2080c1bc742181ded4930842b46e9507372f0b1b963James Dong streamStop = byteStrmStart + strmLen; 2090c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.pStream = byteStrmStart; 2100c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen = strmLen; 2110c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.intraConcealmentMethod = 0; 2120c1bc742181ded4930842b46e9507372f0b1b963James Dong 2130c1bc742181ded4930842b46e9507372f0b1b963James Dong /* get pointer to next packet and the size of packet 2140c1bc742181ded4930842b46e9507372f0b1b963James Dong * (for packetize or nalUnitStream modes) */ 2150c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( (tmp = NextPacket(&decInput.pStream)) != 0 ) 2160c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen = tmp; 2170c1bc742181ded4930842b46e9507372f0b1b963James Dong 2180c1bc742181ded4930842b46e9507372f0b1b963James Dong picDecodeNumber = picDisplayNumber = 1; 2190c1bc742181ded4930842b46e9507372f0b1b963James Dong /* main decoding loop */ 2200c1bc742181ded4930842b46e9507372f0b1b963James Dong do 2210c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2220c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Picture ID is the picture number in decoding order */ 2230c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.picId = picDecodeNumber; 2240c1bc742181ded4930842b46e9507372f0b1b963James Dong 2250c1bc742181ded4930842b46e9507372f0b1b963James Dong /* call API function to perform decoding */ 2260c1bc742181ded4930842b46e9507372f0b1b963James Dong ret = H264SwDecDecode(decInst, &decInput, &decOutput); 2270c1bc742181ded4930842b46e9507372f0b1b963James Dong 2280c1bc742181ded4930842b46e9507372f0b1b963James Dong switch(ret) 2290c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2300c1bc742181ded4930842b46e9507372f0b1b963James Dong 2310c1bc742181ded4930842b46e9507372f0b1b963James Dong case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY: 2320c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Stream headers were successfully decoded 2330c1bc742181ded4930842b46e9507372f0b1b963James Dong * -> stream information is available for query now */ 2340c1bc742181ded4930842b46e9507372f0b1b963James Dong 2350c1bc742181ded4930842b46e9507372f0b1b963James Dong ret = H264SwDecGetInfo(decInst, &decInfo); 2360c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret != H264SWDEC_OK) 2370c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 2380c1bc742181ded4930842b46e9507372f0b1b963James Dong 2390c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("Profile %d\n", decInfo.profile)); 2400c1bc742181ded4930842b46e9507372f0b1b963James Dong 2410c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("Width %d Height %d\n", 2420c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.picWidth, decInfo.picHeight)); 2430c1bc742181ded4930842b46e9507372f0b1b963James Dong 2440c1bc742181ded4930842b46e9507372f0b1b963James Dong if (cropDisplay && decInfo.croppingFlag) 2450c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2460c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("Cropping params: (%d, %d) %dx%d\n", 2470c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.cropParams.cropLeftOffset, 2480c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.cropParams.cropTopOffset, 2490c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.cropParams.cropOutWidth, 2500c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.cropParams.cropOutHeight)); 2510c1bc742181ded4930842b46e9507372f0b1b963James Dong 2520c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Cropped frame size in planar YUV 4:2:0 */ 2530c1bc742181ded4930842b46e9507372f0b1b963James Dong picSize = decInfo.cropParams.cropOutWidth * 2540c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.cropParams.cropOutHeight; 2550c1bc742181ded4930842b46e9507372f0b1b963James Dong picSize = (3 * picSize)/2; 2560c1bc742181ded4930842b46e9507372f0b1b963James Dong tmpImage = malloc(picSize); 2570c1bc742181ded4930842b46e9507372f0b1b963James Dong if (tmpImage == NULL) 2580c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 2590c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2600c1bc742181ded4930842b46e9507372f0b1b963James Dong else 2610c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2620c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Decoder output frame size in planar YUV 4:2:0 */ 2630c1bc742181ded4930842b46e9507372f0b1b963James Dong picSize = decInfo.picWidth * decInfo.picHeight; 2640c1bc742181ded4930842b46e9507372f0b1b963James Dong picSize = (3 * picSize)/2; 2650c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2660c1bc742181ded4930842b46e9507372f0b1b963James Dong 2670c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("videoRange %d, matrixCoefficients %d\n", 2680c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.videoRange, decInfo.matrixCoefficients)); 2690c1bc742181ded4930842b46e9507372f0b1b963James Dong 2700c1bc742181ded4930842b46e9507372f0b1b963James Dong /* update H264SwDecDecode() input structure, number of bytes 2710c1bc742181ded4930842b46e9507372f0b1b963James Dong * "consumed" is computed as difference between the new stream 2720c1bc742181ded4930842b46e9507372f0b1b963James Dong * pointer and old stream pointer */ 2730c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen -= 2740c1bc742181ded4930842b46e9507372f0b1b963James Dong (u32)(decOutput.pStrmCurrPos - decInput.pStream); 2750c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.pStream = decOutput.pStrmCurrPos; 2760c1bc742181ded4930842b46e9507372f0b1b963James Dong 2770c1bc742181ded4930842b46e9507372f0b1b963James Dong /* If -O option not used, generate default file name */ 2780c1bc742181ded4930842b46e9507372f0b1b963James Dong if (outFileName[0] == 0) 2790c1bc742181ded4930842b46e9507372f0b1b963James Dong sprintf(outFileName, "out_w%dh%d.yuv", 2800c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.picWidth, decInfo.picHeight); 2810c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 2820c1bc742181ded4930842b46e9507372f0b1b963James Dong 2830c1bc742181ded4930842b46e9507372f0b1b963James Dong case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY: 2840c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Picture is ready and more data remains in input buffer 2850c1bc742181ded4930842b46e9507372f0b1b963James Dong * -> update H264SwDecDecode() input structure, number of bytes 2860c1bc742181ded4930842b46e9507372f0b1b963James Dong * "consumed" is computed as difference between the new stream 2870c1bc742181ded4930842b46e9507372f0b1b963James Dong * pointer and old stream pointer */ 2880c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen -= 2890c1bc742181ded4930842b46e9507372f0b1b963James Dong (u32)(decOutput.pStrmCurrPos - decInput.pStream); 2900c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.pStream = decOutput.pStrmCurrPos; 2910c1bc742181ded4930842b46e9507372f0b1b963James Dong /* fall through */ 2920c1bc742181ded4930842b46e9507372f0b1b963James Dong 2930c1bc742181ded4930842b46e9507372f0b1b963James Dong case H264SWDEC_PIC_RDY: 2940c1bc742181ded4930842b46e9507372f0b1b963James Dong 2950c1bc742181ded4930842b46e9507372f0b1b963James Dong /*lint -esym(644,tmpImage,picSize) variable initialized at 2960c1bc742181ded4930842b46e9507372f0b1b963James Dong * H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY case */ 2970c1bc742181ded4930842b46e9507372f0b1b963James Dong 2980c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret == H264SWDEC_PIC_RDY) 2990c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen = NextPacket(&decInput.pStream); 3000c1bc742181ded4930842b46e9507372f0b1b963James Dong 3010c1bc742181ded4930842b46e9507372f0b1b963James Dong /* If enough pictures decoded -> force decoding to end 3020c1bc742181ded4930842b46e9507372f0b1b963James Dong * by setting that no more stream is available */ 3030c1bc742181ded4930842b46e9507372f0b1b963James Dong if (maxNumPics && picDecodeNumber == maxNumPics) 3040c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen = 0; 3050c1bc742181ded4930842b46e9507372f0b1b963James Dong 3060c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Increment decoding number for every decoded picture */ 3070c1bc742181ded4930842b46e9507372f0b1b963James Dong picDecodeNumber++; 3080c1bc742181ded4930842b46e9507372f0b1b963James Dong 3090c1bc742181ded4930842b46e9507372f0b1b963James Dong /* use function H264SwDecNextPicture() to obtain next picture 3100c1bc742181ded4930842b46e9507372f0b1b963James Dong * in display order. Function is called until no more images 3110c1bc742181ded4930842b46e9507372f0b1b963James Dong * are ready for display */ 3120c1bc742181ded4930842b46e9507372f0b1b963James Dong while ( H264SwDecNextPicture(decInst, &decPicture, 0) == 3130c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SWDEC_PIC_RDY ) 3140c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3150c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("PIC %d, type %s", picDisplayNumber, 3160c1bc742181ded4930842b46e9507372f0b1b963James Dong decPicture.isIdrPicture ? "IDR" : "NON-IDR")); 3170c1bc742181ded4930842b46e9507372f0b1b963James Dong if (picDisplayNumber != decPicture.picId) 3180c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG((", decoded pic %d", decPicture.picId)); 3190c1bc742181ded4930842b46e9507372f0b1b963James Dong if (decPicture.nbrOfErrMBs) 3200c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3210c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs)); 3220c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3230c1bc742181ded4930842b46e9507372f0b1b963James Dong else 3240c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\n")); 3250c1bc742181ded4930842b46e9507372f0b1b963James Dong fflush(stdout); 3260c1bc742181ded4930842b46e9507372f0b1b963James Dong 3270c1bc742181ded4930842b46e9507372f0b1b963James Dong numErrors += decPicture.nbrOfErrMBs; 3280c1bc742181ded4930842b46e9507372f0b1b963James Dong 3290c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Increment display number for every displayed picture */ 3300c1bc742181ded4930842b46e9507372f0b1b963James Dong picDisplayNumber++; 3310c1bc742181ded4930842b46e9507372f0b1b963James Dong 3320c1bc742181ded4930842b46e9507372f0b1b963James Dong /*lint -esym(644,decInfo) always initialized if pictures 3330c1bc742181ded4930842b46e9507372f0b1b963James Dong * available for display */ 3340c1bc742181ded4930842b46e9507372f0b1b963James Dong 3350c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Write output picture to file */ 3360c1bc742181ded4930842b46e9507372f0b1b963James Dong imageData = (u8*)decPicture.pOutputPicture; 3370c1bc742181ded4930842b46e9507372f0b1b963James Dong if (cropDisplay && decInfo.croppingFlag) 3380c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3390c1bc742181ded4930842b46e9507372f0b1b963James Dong tmp = CropPicture(tmpImage, imageData, 3400c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.picWidth, decInfo.picHeight, 3410c1bc742181ded4930842b46e9507372f0b1b963James Dong &decInfo.cropParams); 3420c1bc742181ded4930842b46e9507372f0b1b963James Dong if (tmp) 3430c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 3440c1bc742181ded4930842b46e9507372f0b1b963James Dong WriteOutput(outFileName, tmpImage, picSize); 3450c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3460c1bc742181ded4930842b46e9507372f0b1b963James Dong else 3470c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3480c1bc742181ded4930842b46e9507372f0b1b963James Dong WriteOutput(outFileName, imageData, picSize); 3490c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3500c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3510c1bc742181ded4930842b46e9507372f0b1b963James Dong 3520c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 3530c1bc742181ded4930842b46e9507372f0b1b963James Dong 3540c1bc742181ded4930842b46e9507372f0b1b963James Dong case H264SWDEC_STRM_PROCESSED: 3550c1bc742181ded4930842b46e9507372f0b1b963James Dong case H264SWDEC_STRM_ERR: 3560c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Input stream was decoded but no picture is ready 3570c1bc742181ded4930842b46e9507372f0b1b963James Dong * -> Get more data */ 3580c1bc742181ded4930842b46e9507372f0b1b963James Dong decInput.dataLen = NextPacket(&decInput.pStream); 3590c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 3600c1bc742181ded4930842b46e9507372f0b1b963James Dong 3610c1bc742181ded4930842b46e9507372f0b1b963James Dong default: 3620c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("FATAL ERROR\n")); 3630c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 3640c1bc742181ded4930842b46e9507372f0b1b963James Dong 3650c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3660c1bc742181ded4930842b46e9507372f0b1b963James Dong /* keep decoding until all data from input stream buffer consumed */ 3670c1bc742181ded4930842b46e9507372f0b1b963James Dong } while (decInput.dataLen > 0); 3680c1bc742181ded4930842b46e9507372f0b1b963James Dong 3690c1bc742181ded4930842b46e9507372f0b1b963James Dong /* if output in display order is preferred, the decoder shall be forced 3700c1bc742181ded4930842b46e9507372f0b1b963James Dong * to output pictures remaining in decoded picture buffer. Use function 3710c1bc742181ded4930842b46e9507372f0b1b963James Dong * H264SwDecNextPicture() to obtain next picture in display order. Function 3720c1bc742181ded4930842b46e9507372f0b1b963James Dong * is called until no more images are ready for display. Second parameter 3730c1bc742181ded4930842b46e9507372f0b1b963James Dong * for the function is set to '1' to indicate that this is end of the 3740c1bc742181ded4930842b46e9507372f0b1b963James Dong * stream and all pictures shall be output */ 3750c1bc742181ded4930842b46e9507372f0b1b963James Dong while (H264SwDecNextPicture(decInst, &decPicture, 1) == H264SWDEC_PIC_RDY) 3760c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3770c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("PIC %d, type %s", picDisplayNumber, 3780c1bc742181ded4930842b46e9507372f0b1b963James Dong decPicture.isIdrPicture ? "IDR" : "NON-IDR")); 3790c1bc742181ded4930842b46e9507372f0b1b963James Dong if (picDisplayNumber != decPicture.picId) 3800c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG((", decoded pic %d", decPicture.picId)); 3810c1bc742181ded4930842b46e9507372f0b1b963James Dong if (decPicture.nbrOfErrMBs) 3820c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3830c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs)); 3840c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3850c1bc742181ded4930842b46e9507372f0b1b963James Dong else 3860c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("\n")); 3870c1bc742181ded4930842b46e9507372f0b1b963James Dong fflush(stdout); 3880c1bc742181ded4930842b46e9507372f0b1b963James Dong 3890c1bc742181ded4930842b46e9507372f0b1b963James Dong numErrors += decPicture.nbrOfErrMBs; 3900c1bc742181ded4930842b46e9507372f0b1b963James Dong 3910c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Increment display number for every displayed picture */ 3920c1bc742181ded4930842b46e9507372f0b1b963James Dong picDisplayNumber++; 3930c1bc742181ded4930842b46e9507372f0b1b963James Dong 3940c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Write output picture to file */ 3950c1bc742181ded4930842b46e9507372f0b1b963James Dong imageData = (u8*)decPicture.pOutputPicture; 3960c1bc742181ded4930842b46e9507372f0b1b963James Dong if (cropDisplay && decInfo.croppingFlag) 3970c1bc742181ded4930842b46e9507372f0b1b963James Dong { 3980c1bc742181ded4930842b46e9507372f0b1b963James Dong tmp = CropPicture(tmpImage, imageData, 3990c1bc742181ded4930842b46e9507372f0b1b963James Dong decInfo.picWidth, decInfo.picHeight, 4000c1bc742181ded4930842b46e9507372f0b1b963James Dong &decInfo.cropParams); 4010c1bc742181ded4930842b46e9507372f0b1b963James Dong if (tmp) 4020c1bc742181ded4930842b46e9507372f0b1b963James Dong return -1; 4030c1bc742181ded4930842b46e9507372f0b1b963James Dong WriteOutput(outFileName, tmpImage, picSize); 4040c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4050c1bc742181ded4930842b46e9507372f0b1b963James Dong else 4060c1bc742181ded4930842b46e9507372f0b1b963James Dong { 4070c1bc742181ded4930842b46e9507372f0b1b963James Dong WriteOutput(outFileName, imageData, picSize); 4080c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4090c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4100c1bc742181ded4930842b46e9507372f0b1b963James Dong 4110c1bc742181ded4930842b46e9507372f0b1b963James Dong /* release decoder instance */ 4120c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecRelease(decInst); 4130c1bc742181ded4930842b46e9507372f0b1b963James Dong 4140c1bc742181ded4930842b46e9507372f0b1b963James Dong if (foutput) 4150c1bc742181ded4930842b46e9507372f0b1b963James Dong fclose(foutput); 4160c1bc742181ded4930842b46e9507372f0b1b963James Dong 4170c1bc742181ded4930842b46e9507372f0b1b963James Dong /* free allocated buffers */ 4180c1bc742181ded4930842b46e9507372f0b1b963James Dong free(byteStrmStart); 4190c1bc742181ded4930842b46e9507372f0b1b963James Dong free(tmpImage); 4200c1bc742181ded4930842b46e9507372f0b1b963James Dong 4210c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("Output file: %s\n", outFileName)); 4220c1bc742181ded4930842b46e9507372f0b1b963James Dong 4230c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("DECODING DONE\n")); 4240c1bc742181ded4930842b46e9507372f0b1b963James Dong if (numErrors || picDecodeNumber == 1) 4250c1bc742181ded4930842b46e9507372f0b1b963James Dong { 4260c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("ERRORS FOUND\n")); 4270c1bc742181ded4930842b46e9507372f0b1b963James Dong return 1; 4280c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4290c1bc742181ded4930842b46e9507372f0b1b963James Dong 4300c1bc742181ded4930842b46e9507372f0b1b963James Dong return 0; 4310c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4320c1bc742181ded4930842b46e9507372f0b1b963James Dong 4330c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 4340c1bc742181ded4930842b46e9507372f0b1b963James Dong 4350c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: WriteOutput 4360c1bc742181ded4930842b46e9507372f0b1b963James Dong 4370c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 4380c1bc742181ded4930842b46e9507372f0b1b963James Dong Write picture pointed by data to file. Size of the 4390c1bc742181ded4930842b46e9507372f0b1b963James Dong picture in pixels is indicated by picSize. 4400c1bc742181ded4930842b46e9507372f0b1b963James Dong 4410c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 4420c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid WriteOutput(char *filename, u8 *data, u32 picSize) 4430c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 4440c1bc742181ded4930842b46e9507372f0b1b963James Dong 4450c1bc742181ded4930842b46e9507372f0b1b963James Dong /* foutput is global file pointer */ 4460c1bc742181ded4930842b46e9507372f0b1b963James Dong if (foutput == NULL) 4470c1bc742181ded4930842b46e9507372f0b1b963James Dong { 4480c1bc742181ded4930842b46e9507372f0b1b963James Dong /* open output file for writing, can be disabled with define. 4490c1bc742181ded4930842b46e9507372f0b1b963James Dong * If file open fails -> exit */ 4500c1bc742181ded4930842b46e9507372f0b1b963James Dong if (strcmp(filename, "none") != 0) 4510c1bc742181ded4930842b46e9507372f0b1b963James Dong { 4520c1bc742181ded4930842b46e9507372f0b1b963James Dong#if !defined(_NO_OUT) 4530c1bc742181ded4930842b46e9507372f0b1b963James Dong foutput = fopen(filename, "wb"); 4540c1bc742181ded4930842b46e9507372f0b1b963James Dong if (foutput == NULL) 4550c1bc742181ded4930842b46e9507372f0b1b963James Dong { 4560c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("UNABLE TO OPEN OUTPUT FILE\n")); 4570c1bc742181ded4930842b46e9507372f0b1b963James Dong exit(100); 4580c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4590c1bc742181ded4930842b46e9507372f0b1b963James Dong#endif 4600c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4610c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4620c1bc742181ded4930842b46e9507372f0b1b963James Dong 4630c1bc742181ded4930842b46e9507372f0b1b963James Dong if (foutput && data) 4640c1bc742181ded4930842b46e9507372f0b1b963James Dong fwrite(data, 1, picSize, foutput); 4650c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4660c1bc742181ded4930842b46e9507372f0b1b963James Dong 4670c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 4680c1bc742181ded4930842b46e9507372f0b1b963James Dong 4690c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: NextPacket 4700c1bc742181ded4930842b46e9507372f0b1b963James Dong 4710c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 4720c1bc742181ded4930842b46e9507372f0b1b963James Dong Get the pointer to start of next packet in input stream. Uses 4730c1bc742181ded4930842b46e9507372f0b1b963James Dong global variables 'packetize' and 'nalUnitStream' to determine the 4740c1bc742181ded4930842b46e9507372f0b1b963James Dong decoder input stream mode and 'streamStop' to determine the end 4750c1bc742181ded4930842b46e9507372f0b1b963James Dong of stream. There are three possible stream modes: 4760c1bc742181ded4930842b46e9507372f0b1b963James Dong default - the whole stream at once 4770c1bc742181ded4930842b46e9507372f0b1b963James Dong packetize - a single NAL-unit with start code prefix 4780c1bc742181ded4930842b46e9507372f0b1b963James Dong nalUnitStream - a single NAL-unit without start code prefix 4790c1bc742181ded4930842b46e9507372f0b1b963James Dong 4800c1bc742181ded4930842b46e9507372f0b1b963James Dong pStrm stores pointer to the start of previous decoder input and is 4810c1bc742181ded4930842b46e9507372f0b1b963James Dong replaced with pointer to the start of the next decoder input. 4820c1bc742181ded4930842b46e9507372f0b1b963James Dong 4830c1bc742181ded4930842b46e9507372f0b1b963James Dong Returns the packet size in bytes 4840c1bc742181ded4930842b46e9507372f0b1b963James Dong 4850c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 4860c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 NextPacket(u8 **pStrm) 4870c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 4880c1bc742181ded4930842b46e9507372f0b1b963James Dong 4890c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 index; 4900c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 maxIndex; 4910c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 zeroCount; 4920c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 *stream; 4930c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 byte; 4940c1bc742181ded4930842b46e9507372f0b1b963James Dong static u32 prevIndex=0; 4950c1bc742181ded4930842b46e9507372f0b1b963James Dong 4960c1bc742181ded4930842b46e9507372f0b1b963James Dong /* For default stream mode all the stream is in first packet */ 4970c1bc742181ded4930842b46e9507372f0b1b963James Dong if (!packetize && !nalUnitStream) 4980c1bc742181ded4930842b46e9507372f0b1b963James Dong return 0; 4990c1bc742181ded4930842b46e9507372f0b1b963James Dong 5000c1bc742181ded4930842b46e9507372f0b1b963James Dong index = 0; 5010c1bc742181ded4930842b46e9507372f0b1b963James Dong stream = *pStrm + prevIndex; 5020c1bc742181ded4930842b46e9507372f0b1b963James Dong maxIndex = (u32)(streamStop - stream); 5030c1bc742181ded4930842b46e9507372f0b1b963James Dong 5040c1bc742181ded4930842b46e9507372f0b1b963James Dong if (maxIndex == 0) 5050c1bc742181ded4930842b46e9507372f0b1b963James Dong return(0); 5060c1bc742181ded4930842b46e9507372f0b1b963James Dong 5070c1bc742181ded4930842b46e9507372f0b1b963James Dong /* leading zeros of first NAL unit */ 5080c1bc742181ded4930842b46e9507372f0b1b963James Dong do 5090c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5100c1bc742181ded4930842b46e9507372f0b1b963James Dong byte = stream[index++]; 5110c1bc742181ded4930842b46e9507372f0b1b963James Dong } while (byte != 1 && index < maxIndex); 5120c1bc742181ded4930842b46e9507372f0b1b963James Dong 5130c1bc742181ded4930842b46e9507372f0b1b963James Dong /* invalid start code prefix */ 5140c1bc742181ded4930842b46e9507372f0b1b963James Dong if (index == maxIndex || index < 3) 5150c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5160c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("INVALID BYTE STREAM\n")); 5170c1bc742181ded4930842b46e9507372f0b1b963James Dong exit(100); 5180c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5190c1bc742181ded4930842b46e9507372f0b1b963James Dong 5200c1bc742181ded4930842b46e9507372f0b1b963James Dong /* nalUnitStream is without start code prefix */ 5210c1bc742181ded4930842b46e9507372f0b1b963James Dong if (nalUnitStream) 5220c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5230c1bc742181ded4930842b46e9507372f0b1b963James Dong stream += index; 5240c1bc742181ded4930842b46e9507372f0b1b963James Dong maxIndex -= index; 5250c1bc742181ded4930842b46e9507372f0b1b963James Dong index = 0; 5260c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5270c1bc742181ded4930842b46e9507372f0b1b963James Dong 5280c1bc742181ded4930842b46e9507372f0b1b963James Dong zeroCount = 0; 5290c1bc742181ded4930842b46e9507372f0b1b963James Dong 5300c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Search stream for next start code prefix */ 5310c1bc742181ded4930842b46e9507372f0b1b963James Dong /*lint -e(716) while(1) used consciously */ 5320c1bc742181ded4930842b46e9507372f0b1b963James Dong while (1) 5330c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5340c1bc742181ded4930842b46e9507372f0b1b963James Dong byte = stream[index++]; 5350c1bc742181ded4930842b46e9507372f0b1b963James Dong if (!byte) 5360c1bc742181ded4930842b46e9507372f0b1b963James Dong zeroCount++; 5370c1bc742181ded4930842b46e9507372f0b1b963James Dong 5380c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( (byte == 0x01) && (zeroCount >= 2) ) 5390c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5400c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Start code prefix has two zeros 5410c1bc742181ded4930842b46e9507372f0b1b963James Dong * Third zero is assumed to be leading zero of next packet 5420c1bc742181ded4930842b46e9507372f0b1b963James Dong * Fourth and more zeros are assumed to be trailing zeros of this 5430c1bc742181ded4930842b46e9507372f0b1b963James Dong * packet */ 5440c1bc742181ded4930842b46e9507372f0b1b963James Dong if (zeroCount > 3) 5450c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5460c1bc742181ded4930842b46e9507372f0b1b963James Dong index -= 4; 5470c1bc742181ded4930842b46e9507372f0b1b963James Dong zeroCount -= 3; 5480c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5490c1bc742181ded4930842b46e9507372f0b1b963James Dong else 5500c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5510c1bc742181ded4930842b46e9507372f0b1b963James Dong index -= zeroCount+1; 5520c1bc742181ded4930842b46e9507372f0b1b963James Dong zeroCount = 0; 5530c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5540c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 5550c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5560c1bc742181ded4930842b46e9507372f0b1b963James Dong else if (byte) 5570c1bc742181ded4930842b46e9507372f0b1b963James Dong zeroCount = 0; 5580c1bc742181ded4930842b46e9507372f0b1b963James Dong 5590c1bc742181ded4930842b46e9507372f0b1b963James Dong if (index == maxIndex) 5600c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5610c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 5620c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5630c1bc742181ded4930842b46e9507372f0b1b963James Dong 5640c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5650c1bc742181ded4930842b46e9507372f0b1b963James Dong 5660c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Store pointer to the beginning of the packet */ 5670c1bc742181ded4930842b46e9507372f0b1b963James Dong *pStrm = stream; 5680c1bc742181ded4930842b46e9507372f0b1b963James Dong prevIndex = index; 5690c1bc742181ded4930842b46e9507372f0b1b963James Dong 5700c1bc742181ded4930842b46e9507372f0b1b963James Dong /* nalUnitStream is without trailing zeros */ 5710c1bc742181ded4930842b46e9507372f0b1b963James Dong if (nalUnitStream) 5720c1bc742181ded4930842b46e9507372f0b1b963James Dong index -= zeroCount; 5730c1bc742181ded4930842b46e9507372f0b1b963James Dong 5740c1bc742181ded4930842b46e9507372f0b1b963James Dong return(index); 5750c1bc742181ded4930842b46e9507372f0b1b963James Dong 5760c1bc742181ded4930842b46e9507372f0b1b963James Dong} 5770c1bc742181ded4930842b46e9507372f0b1b963James Dong 5780c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 5790c1bc742181ded4930842b46e9507372f0b1b963James Dong 5800c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: CropPicture 5810c1bc742181ded4930842b46e9507372f0b1b963James Dong 5820c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 5830c1bc742181ded4930842b46e9507372f0b1b963James Dong Perform cropping for picture. Input picture pInImage with dimensions 5840c1bc742181ded4930842b46e9507372f0b1b963James Dong picWidth x picHeight is cropped with pCropParams and the resulting 5850c1bc742181ded4930842b46e9507372f0b1b963James Dong picture is stored in pOutImage. 5860c1bc742181ded4930842b46e9507372f0b1b963James Dong 5870c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 5880c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 CropPicture(u8 *pOutImage, u8 *pInImage, 5890c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 picWidth, u32 picHeight, CropParams *pCropParams) 5900c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 5910c1bc742181ded4930842b46e9507372f0b1b963James Dong 5920c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 i, j; 5930c1bc742181ded4930842b46e9507372f0b1b963James Dong u32 outWidth, outHeight; 5940c1bc742181ded4930842b46e9507372f0b1b963James Dong u8 *pOut, *pIn; 5950c1bc742181ded4930842b46e9507372f0b1b963James Dong 5960c1bc742181ded4930842b46e9507372f0b1b963James Dong if (pOutImage == NULL || pInImage == NULL || pCropParams == NULL || 5970c1bc742181ded4930842b46e9507372f0b1b963James Dong !picWidth || !picHeight) 5980c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5990c1bc742181ded4930842b46e9507372f0b1b963James Dong /* just to prevent lint warning, returning non-zero will result in 6000c1bc742181ded4930842b46e9507372f0b1b963James Dong * return without freeing the memory */ 6010c1bc742181ded4930842b46e9507372f0b1b963James Dong free(pOutImage); 6020c1bc742181ded4930842b46e9507372f0b1b963James Dong return(1); 6030c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6040c1bc742181ded4930842b46e9507372f0b1b963James Dong 6050c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( ((pCropParams->cropLeftOffset + pCropParams->cropOutWidth) > 6060c1bc742181ded4930842b46e9507372f0b1b963James Dong picWidth ) || 6070c1bc742181ded4930842b46e9507372f0b1b963James Dong ((pCropParams->cropTopOffset + pCropParams->cropOutHeight) > 6080c1bc742181ded4930842b46e9507372f0b1b963James Dong picHeight ) ) 6090c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6100c1bc742181ded4930842b46e9507372f0b1b963James Dong /* just to prevent lint warning, returning non-zero will result in 6110c1bc742181ded4930842b46e9507372f0b1b963James Dong * return without freeing the memory */ 6120c1bc742181ded4930842b46e9507372f0b1b963James Dong free(pOutImage); 6130c1bc742181ded4930842b46e9507372f0b1b963James Dong return(1); 6140c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6150c1bc742181ded4930842b46e9507372f0b1b963James Dong 6160c1bc742181ded4930842b46e9507372f0b1b963James Dong outWidth = pCropParams->cropOutWidth; 6170c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeight = pCropParams->cropOutHeight; 6180c1bc742181ded4930842b46e9507372f0b1b963James Dong 6190c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculate starting pointer for luma */ 6200c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn = pInImage + pCropParams->cropTopOffset*picWidth + 6210c1bc742181ded4930842b46e9507372f0b1b963James Dong pCropParams->cropLeftOffset; 6220c1bc742181ded4930842b46e9507372f0b1b963James Dong pOut = pOutImage; 6230c1bc742181ded4930842b46e9507372f0b1b963James Dong 6240c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Copy luma pixel values */ 6250c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = outHeight; i; i--) 6260c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6270c1bc742181ded4930842b46e9507372f0b1b963James Dong for (j = outWidth; j; j--) 6280c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6290c1bc742181ded4930842b46e9507372f0b1b963James Dong *pOut++ = *pIn++; 6300c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6310c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn += picWidth - outWidth; 6320c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6330c1bc742181ded4930842b46e9507372f0b1b963James Dong 6340c1bc742181ded4930842b46e9507372f0b1b963James Dong outWidth >>= 1; 6350c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeight >>= 1; 6360c1bc742181ded4930842b46e9507372f0b1b963James Dong 6370c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculate starting pointer for cb */ 6380c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn = pInImage + picWidth*picHeight + 6390c1bc742181ded4930842b46e9507372f0b1b963James Dong pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2; 6400c1bc742181ded4930842b46e9507372f0b1b963James Dong 6410c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Copy cb pixel values */ 6420c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = outHeight; i; i--) 6430c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6440c1bc742181ded4930842b46e9507372f0b1b963James Dong for (j = outWidth; j; j--) 6450c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6460c1bc742181ded4930842b46e9507372f0b1b963James Dong *pOut++ = *pIn++; 6470c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6480c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn += picWidth/2 - outWidth; 6490c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6500c1bc742181ded4930842b46e9507372f0b1b963James Dong 6510c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculate starting pointer for cr */ 6520c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn = pInImage + 5*picWidth*picHeight/4 + 6530c1bc742181ded4930842b46e9507372f0b1b963James Dong pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2; 6540c1bc742181ded4930842b46e9507372f0b1b963James Dong 6550c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Copy cr pixel values */ 6560c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = outHeight; i; i--) 6570c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6580c1bc742181ded4930842b46e9507372f0b1b963James Dong for (j = outWidth; j; j--) 6590c1bc742181ded4930842b46e9507372f0b1b963James Dong { 6600c1bc742181ded4930842b46e9507372f0b1b963James Dong *pOut++ = *pIn++; 6610c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6620c1bc742181ded4930842b46e9507372f0b1b963James Dong pIn += picWidth/2 - outWidth; 6630c1bc742181ded4930842b46e9507372f0b1b963James Dong } 6640c1bc742181ded4930842b46e9507372f0b1b963James Dong 6650c1bc742181ded4930842b46e9507372f0b1b963James Dong return (0); 6660c1bc742181ded4930842b46e9507372f0b1b963James Dong} 6670c1bc742181ded4930842b46e9507372f0b1b963James Dong 6680c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 6690c1bc742181ded4930842b46e9507372f0b1b963James Dong 6700c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: H264SwDecTrace 6710c1bc742181ded4930842b46e9507372f0b1b963James Dong 6720c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 6730c1bc742181ded4930842b46e9507372f0b1b963James Dong Example implementation of H264SwDecTrace function. Prototype of this 6740c1bc742181ded4930842b46e9507372f0b1b963James Dong function is given in H264SwDecApi.h. This implementation appends 6750c1bc742181ded4930842b46e9507372f0b1b963James Dong trace messages to file named 'dec_api.trc'. 6760c1bc742181ded4930842b46e9507372f0b1b963James Dong 6770c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 6780c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid H264SwDecTrace(char *string) 6790c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 6800c1bc742181ded4930842b46e9507372f0b1b963James Dong FILE *fp; 6810c1bc742181ded4930842b46e9507372f0b1b963James Dong 6820c1bc742181ded4930842b46e9507372f0b1b963James Dong fp = fopen("dec_api.trc", "at"); 6830c1bc742181ded4930842b46e9507372f0b1b963James Dong 6840c1bc742181ded4930842b46e9507372f0b1b963James Dong if (!fp) 6850c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 6860c1bc742181ded4930842b46e9507372f0b1b963James Dong 6870c1bc742181ded4930842b46e9507372f0b1b963James Dong fwrite(string, 1, strlen(string), fp); 6880c1bc742181ded4930842b46e9507372f0b1b963James Dong fwrite("\n", 1,1, fp); 6890c1bc742181ded4930842b46e9507372f0b1b963James Dong 6900c1bc742181ded4930842b46e9507372f0b1b963James Dong fclose(fp); 6910c1bc742181ded4930842b46e9507372f0b1b963James Dong} 6920c1bc742181ded4930842b46e9507372f0b1b963James Dong 6930c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 6940c1bc742181ded4930842b46e9507372f0b1b963James Dong 6950c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: H264SwDecMalloc 6960c1bc742181ded4930842b46e9507372f0b1b963James Dong 6970c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 6980c1bc742181ded4930842b46e9507372f0b1b963James Dong Example implementation of H264SwDecMalloc function. Prototype of this 6990c1bc742181ded4930842b46e9507372f0b1b963James Dong function is given in H264SwDecApi.h. This implementation uses 7000c1bc742181ded4930842b46e9507372f0b1b963James Dong library function malloc for allocation of memory. 7010c1bc742181ded4930842b46e9507372f0b1b963James Dong 7020c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 7030c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid* H264SwDecMalloc(u32 size) 7040c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 7050c1bc742181ded4930842b46e9507372f0b1b963James Dong 7060c1bc742181ded4930842b46e9507372f0b1b963James Dong#if defined(CHECK_MEMORY_USAGE) 7070c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Note that if the decoder has to free and reallocate some of the buffers 7080c1bc742181ded4930842b46e9507372f0b1b963James Dong * the total value will be invalid */ 7090c1bc742181ded4930842b46e9507372f0b1b963James Dong static u32 numBytes = 0; 7100c1bc742181ded4930842b46e9507372f0b1b963James Dong numBytes += size; 7110c1bc742181ded4930842b46e9507372f0b1b963James Dong DEBUG(("Allocated %d bytes, total %d\n", size, numBytes)); 7120c1bc742181ded4930842b46e9507372f0b1b963James Dong#endif 7130c1bc742181ded4930842b46e9507372f0b1b963James Dong 7140c1bc742181ded4930842b46e9507372f0b1b963James Dong return malloc(size); 7150c1bc742181ded4930842b46e9507372f0b1b963James Dong} 7160c1bc742181ded4930842b46e9507372f0b1b963James Dong 7170c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 7180c1bc742181ded4930842b46e9507372f0b1b963James Dong 7190c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: H264SwDecFree 7200c1bc742181ded4930842b46e9507372f0b1b963James Dong 7210c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 7220c1bc742181ded4930842b46e9507372f0b1b963James Dong Example implementation of H264SwDecFree function. Prototype of this 7230c1bc742181ded4930842b46e9507372f0b1b963James Dong function is given in H264SwDecApi.h. This implementation uses 7240c1bc742181ded4930842b46e9507372f0b1b963James Dong library function free for freeing of memory. 7250c1bc742181ded4930842b46e9507372f0b1b963James Dong 7260c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 7270c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid H264SwDecFree(void *ptr) 7280c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 7290c1bc742181ded4930842b46e9507372f0b1b963James Dong free(ptr); 7300c1bc742181ded4930842b46e9507372f0b1b963James Dong} 7310c1bc742181ded4930842b46e9507372f0b1b963James Dong 7320c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 7330c1bc742181ded4930842b46e9507372f0b1b963James Dong 7340c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: H264SwDecMemcpy 7350c1bc742181ded4930842b46e9507372f0b1b963James Dong 7360c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 7370c1bc742181ded4930842b46e9507372f0b1b963James Dong Example implementation of H264SwDecMemcpy function. Prototype of this 7380c1bc742181ded4930842b46e9507372f0b1b963James Dong function is given in H264SwDecApi.h. This implementation uses 7390c1bc742181ded4930842b46e9507372f0b1b963James Dong library function memcpy to copy src to dest. 7400c1bc742181ded4930842b46e9507372f0b1b963James Dong 7410c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 7420c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid H264SwDecMemcpy(void *dest, void *src, u32 count) 7430c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 7440c1bc742181ded4930842b46e9507372f0b1b963James Dong memcpy(dest, src, count); 7450c1bc742181ded4930842b46e9507372f0b1b963James Dong} 7460c1bc742181ded4930842b46e9507372f0b1b963James Dong 7470c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------ 7480c1bc742181ded4930842b46e9507372f0b1b963James Dong 7490c1bc742181ded4930842b46e9507372f0b1b963James Dong Function name: H264SwDecMemset 7500c1bc742181ded4930842b46e9507372f0b1b963James Dong 7510c1bc742181ded4930842b46e9507372f0b1b963James Dong Purpose: 7520c1bc742181ded4930842b46e9507372f0b1b963James Dong Example implementation of H264SwDecMemset function. Prototype of this 7530c1bc742181ded4930842b46e9507372f0b1b963James Dong function is given in H264SwDecApi.h. This implementation uses 7540c1bc742181ded4930842b46e9507372f0b1b963James Dong library function memset to set content of memory area pointed by ptr. 7550c1bc742181ded4930842b46e9507372f0b1b963James Dong 7560c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/ 7570c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid H264SwDecMemset(void *ptr, i32 value, u32 count) 7580c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 7590c1bc742181ded4930842b46e9507372f0b1b963James Dong memset(ptr, value, count); 7600c1bc742181ded4930842b46e9507372f0b1b963James Dong} 7610c1bc742181ded4930842b46e9507372f0b1b963James Dong 762