PageRenderTime 83ms CodeModel.GetById 15ms app.highlight 61ms RepoModel.GetById 1ms app.codeStats 0ms

/H264Dec/source/DecTestBench.c

http://github.com/mbebenita/Broadway
C | 820 lines | 484 code | 118 blank | 218 comment | 111 complexity | f4340705957a17a27c73620fdcc428c5 MD5 | raw file
  1/*
  2 * Copyright (C) 2009 The Android Open Source Project
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *      http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 * See the License for the specific language governing permissions and
 14 * limitations under the License.
 15 */
 16
 17#include "H264SwDecApi.h"
 18#include <stdio.h>
 19#include <stdlib.h>
 20#include <string.h>
 21
 22#include "SDL/SDL.h"
 23
 24/*------------------------------------------------------------------------------
 25    Module defines
 26------------------------------------------------------------------------------*/
 27
 28/* CHECK_MEMORY_USAGE prints and sums the memory allocated in calls to
 29 * H264SwDecMalloc() */
 30/* #define CHECK_MEMORY_USAGE */
 31
 32/* _NO_OUT disables output file writing */
 33/* #define _NO_OUT */
 34
 35/* Debug prints */
 36#define DEBUG(argv) printf argv
 37
 38/* CVS tag name for identification */
 39const char tagName[256] = "$Name: FIRST_ANDROID_COPYRIGHT $";
 40
 41void WriteOutput(char *filename, u8 *data, u32 picSize);
 42u32 NextPacket(u8 **pStrm);
 43u32 CropPicture(u8 *pOutImage, u8 *pInImage,
 44    u32 picWidth, u32 picHeight, CropParams *pCropParams);
 45
 46/* Global variables for stream handling */
 47u8 *streamStop = NULL;
 48u32 packetize = 0;
 49u32 nalUnitStream = 0;
 50FILE *foutput = NULL;
 51
 52#define RENDER 1
 53void DrawOutput(u8 *data, u32 picWidth, u32 picHeight);
 54SDL_Surface* screen = NULL;
 55
 56#ifdef SOC_DESIGNER
 57
 58// Initialisation function defined in InitCache.s
 59extern void cache_init(void);
 60
 61/*------------------------------------------------------------------------------
 62
 63    Function name:  $Sub$$main
 64
 65    Purpose:
 66        This function is called at the end of the C library initialisation and
 67        before main. Its purpose is to do any further initialisation before the
 68        application start.
 69
 70------------------------------------------------------------------------------*/
 71int $Sub$$main(char argc, char * argv[])
 72{
 73  cache_init();                    // does some extra setup work setting up caches
 74  return $Super$$main(argc, argv); // calls the original function
 75}
 76#endif
 77
 78/*------------------------------------------------------------------------------
 79
 80    Function name:  main
 81
 82    Purpose:
 83        main function of decoder testbench. Provides command line interface
 84        with file I/O for H.264 decoder. Prints out the usage information
 85        when executed without arguments.
 86
 87------------------------------------------------------------------------------*/
 88
 89#ifdef LINUX
 90int main(int argc, char **argv) {
 91#else
 92int SDL_main(int argc, char **argv) {
 93#endif
 94
 95    u32 i, tmp;
 96    u32 maxNumPics = 0;
 97    u8 *byteStrmStart;
 98    u8 *imageData;
 99    u8 *tmpImage = NULL;
100    u32 strmLen;
101    u32 picSize;
102    H264SwDecInst decInst;
103    H264SwDecRet ret;
104    H264SwDecInput decInput;
105    H264SwDecOutput decOutput;
106    H264SwDecPicture decPicture;
107    H264SwDecInfo decInfo;
108    H264SwDecApiVersion decVer;
109    u32 picDecodeNumber;
110    u32 picDisplayNumber;
111    u32 numErrors = 0;
112    u32 cropDisplay = 0;
113    u32 disableOutputReordering = 0;
114
115    FILE *finput;
116
117    char outFileName[256] = "";
118
119    /* Print API version number */
120    decVer = H264SwDecGetAPIVersion();
121    DEBUG(("H.264 Decoder API v%d.%d\n", decVer.major, decVer.minor));
122
123    /* Print tag name if '-T' argument present */
124    if ( argc > 1 && strcmp(argv[1], "-T") == 0 )
125    {
126        DEBUG(("%s\n", tagName));
127        return 0;
128    }
129
130    /* Check that enough command line arguments given, if not -> print usage
131     * information out */
132    if (argc < 2)
133    {
134        DEBUG((
135            "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file.h264\n",
136            argv[0]));
137        DEBUG(("\t-Nn forces decoding to stop after n pictures\n"));
138#if defined(_NO_OUT)
139        DEBUG(("\t-Ooutfile output writing disabled at compile time\n"));
140#else
141        DEBUG(("\t-Ooutfile write output to \"outfile\" (default out_wxxxhyyy.yuv)\n"));
142        DEBUG(("\t-Onone does not write output\n"));
143#endif
144        DEBUG(("\t-P packet-by-packet mode\n"));
145        DEBUG(("\t-U NAL unit stream mode\n"));
146        DEBUG(("\t-C display cropped image (default decoded image)\n"));
147        DEBUG(("\t-R disable DPB output reordering\n"));
148        DEBUG(("\t-T to print tag name and exit\n"));
149        return 0;
150    }
151
152    /* read command line arguments */
153    for (i = 1; i < (u32)(argc-1); i++)
154    {
155        if ( strncmp(argv[i], "-N", 2) == 0 )
156        {
157            maxNumPics = (u32)atoi(argv[i]+2);
158        }
159        else if ( strncmp(argv[i], "-O", 2) == 0 )
160        {
161            strcpy(outFileName, argv[i]+2);
162        }
163        else if ( strcmp(argv[i], "-P") == 0 )
164        {
165            packetize = 1;
166        }
167        else if ( strcmp(argv[i], "-U") == 0 )
168        {
169            nalUnitStream = 1;
170        }
171        else if ( strcmp(argv[i], "-C") == 0 )
172        {
173            cropDisplay = 1;
174        }
175        else if ( strcmp(argv[i], "-R") == 0 )
176        {
177            disableOutputReordering = 1;
178        }
179    }
180
181    /* open input file for reading, file name given by user. If file open
182     * fails -> exit */
183    finput = fopen(argv[argc-1],"rb");
184    if (finput == NULL)
185    {
186        DEBUG(("UNABLE TO OPEN INPUT FILE\n"));
187        return -1;
188    }
189
190    /* check size of the input file -> length of the stream in bytes */
191    fseek(finput,0L,SEEK_END);
192    strmLen = (u32)ftell(finput);
193    rewind(finput);
194
195    /* allocate memory for stream buffer. if unsuccessful -> exit */
196    byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen);
197    if (byteStrmStart == NULL)
198    {
199        DEBUG(("UNABLE TO ALLOCATE MEMORY\n"));
200        return -1;
201    }
202
203    /* read input stream from file to buffer and close input file */
204    fread(byteStrmStart, sizeof(u8), strmLen, finput);
205    fclose(finput);
206
207    /* initialize decoder. If unsuccessful -> exit */
208    ret = H264SwDecInit(&decInst, disableOutputReordering);
209    if (ret != H264SWDEC_OK)
210    {
211        DEBUG(("DECODER INITIALIZATION FAILED\n"));
212        free(byteStrmStart);
213        return -1;
214    }
215
216#if RENDER
217    SDL_Init(SDL_INIT_VIDEO);
218#endif
219
220    /* initialize H264SwDecDecode() input structure */
221    streamStop = byteStrmStart + strmLen;
222    decInput.pStream = byteStrmStart;
223    decInput.dataLen = strmLen;
224    decInput.intraConcealmentMethod = 0;
225
226    /* get pointer to next packet and the size of packet
227     * (for packetize or nalUnitStream modes) */
228    if ( (tmp = NextPacket(&decInput.pStream)) != 0 )
229        decInput.dataLen = tmp;
230
231    picDecodeNumber = picDisplayNumber = 1;
232    /* main decoding loop */
233    do
234    {
235        /* Picture ID is the picture number in decoding order */
236        decInput.picId = picDecodeNumber;
237
238        /* call API function to perform decoding */
239        ret = H264SwDecDecode(decInst, &decInput, &decOutput);
240
241        switch(ret)
242        {
243
244            case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:
245                /* Stream headers were successfully decoded
246                 * -> stream information is available for query now */
247
248                ret = H264SwDecGetInfo(decInst, &decInfo);
249                if (ret != H264SWDEC_OK)
250                    return -1;
251
252                DEBUG(("Profile %d\n", decInfo.profile));
253
254                DEBUG(("Width %d Height %d\n",
255                    decInfo.picWidth, decInfo.picHeight));
256
257#if RENDER
258                if (!screen) {
259                    screen = SDL_SetVideoMode(decInfo.picWidth, decInfo.picHeight, 32, SDL_HWSURFACE | SDL_RESIZABLE);
260                }
261                SDL_LockSurface(screen);
262#endif
263
264                if (cropDisplay && decInfo.croppingFlag)
265                {
266                    DEBUG(("Cropping params: (%d, %d) %dx%d\n",
267                        decInfo.cropParams.cropLeftOffset,
268                        decInfo.cropParams.cropTopOffset,
269                        decInfo.cropParams.cropOutWidth,
270                        decInfo.cropParams.cropOutHeight));
271
272                    /* Cropped frame size in planar YUV 4:2:0 */
273                    picSize = decInfo.cropParams.cropOutWidth *
274                              decInfo.cropParams.cropOutHeight;
275                    picSize = (3 * picSize)/2;
276                    tmpImage = malloc(picSize);
277                    if (tmpImage == NULL)
278                        return -1;
279                }
280                else
281                {
282                    /* Decoder output frame size in planar YUV 4:2:0 */
283                    picSize = decInfo.picWidth * decInfo.picHeight;
284                    picSize = (3 * picSize)/2;
285                }
286
287                DEBUG(("videoRange %d, matrixCoefficients %d\n",
288                    decInfo.videoRange, decInfo.matrixCoefficients));
289
290                /* update H264SwDecDecode() input structure, number of bytes
291                 * "consumed" is computed as difference between the new stream
292                 * pointer and old stream pointer */
293                decInput.dataLen -=
294                    (u32)(decOutput.pStrmCurrPos - decInput.pStream);
295                decInput.pStream = decOutput.pStrmCurrPos;
296
297                /* If -O option not used, generate default file name */
298                if (outFileName[0] == 0)
299                    sprintf(outFileName, "out_w%dh%d.yuv",
300                            decInfo.picWidth, decInfo.picHeight);
301                break;
302
303            case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
304                /* Picture is ready and more data remains in input buffer
305                 * -> update H264SwDecDecode() input structure, number of bytes
306                 * "consumed" is computed as difference between the new stream
307                 * pointer and old stream pointer */
308                decInput.dataLen -=
309                    (u32)(decOutput.pStrmCurrPos - decInput.pStream);
310                decInput.pStream = decOutput.pStrmCurrPos;
311                /* fall through */
312
313            case H264SWDEC_PIC_RDY:
314
315                /*lint -esym(644,tmpImage,picSize) variable initialized at
316                 * H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY case */
317
318                if (ret == H264SWDEC_PIC_RDY)
319                    decInput.dataLen = NextPacket(&decInput.pStream);
320
321                /* If enough pictures decoded -> force decoding to end
322                 * by setting that no more stream is available */
323                if (maxNumPics && picDecodeNumber == maxNumPics)
324                    decInput.dataLen = 0;
325
326                /* Increment decoding number for every decoded picture */
327                picDecodeNumber++;
328
329                /* use function H264SwDecNextPicture() to obtain next picture
330                 * in display order. Function is called until no more images
331                 * are ready for display */
332                while ( H264SwDecNextPicture(decInst, &decPicture, 0) ==
333                        H264SWDEC_PIC_RDY )
334                {
335                    DEBUG(("PIC %d, type %s", picDisplayNumber,
336                        decPicture.isIdrPicture ? "IDR" : "NON-IDR"));
337                    if (picDisplayNumber != decPicture.picId)
338                        DEBUG((", decoded pic %d", decPicture.picId));
339                    if (decPicture.nbrOfErrMBs)
340                    {
341                        DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs));
342                    }
343                    else
344                        DEBUG(("\n"));
345                    fflush(stdout);
346
347                    numErrors += decPicture.nbrOfErrMBs;
348
349                    /* Increment display number for every displayed picture */
350                    picDisplayNumber++;
351
352                    /*lint -esym(644,decInfo) always initialized if pictures
353                     * available for display */
354
355                    /* Write output picture to file */
356                    imageData = (u8*)decPicture.pOutputPicture;
357                    if (cropDisplay && decInfo.croppingFlag)
358                    {
359                        tmp = CropPicture(tmpImage, imageData,
360                            decInfo.picWidth, decInfo.picHeight,
361                            &decInfo.cropParams);
362                        if (tmp)
363                            return -1;
364                        WriteOutput(outFileName, tmpImage, picSize);
365                    }
366                    else
367                    {
368                        WriteOutput(outFileName, imageData, picSize);
369                        DrawOutput(imageData, decInfo.picWidth, decInfo.picHeight);
370                    }
371                }
372
373                break;
374
375            case H264SWDEC_STRM_PROCESSED:
376            case H264SWDEC_STRM_ERR:
377                /* Input stream was decoded but no picture is ready
378                 * -> Get more data */
379                decInput.dataLen = NextPacket(&decInput.pStream);
380                break;
381
382            default:
383                DEBUG(("FATAL ERROR\n"));
384                return -1;
385
386        }
387    /* keep decoding until all data from input stream buffer consumed */
388    } while (decInput.dataLen > 0);
389
390    /* if output in display order is preferred, the decoder shall be forced
391     * to output pictures remaining in decoded picture buffer. Use function
392     * H264SwDecNextPicture() to obtain next picture in display order. Function
393     * is called until no more images are ready for display. Second parameter
394     * for the function is set to '1' to indicate that this is end of the
395     * stream and all pictures shall be output */
396    while (H264SwDecNextPicture(decInst, &decPicture, 1) == H264SWDEC_PIC_RDY)
397    {
398        DEBUG(("PIC %d, type %s", picDisplayNumber,
399            decPicture.isIdrPicture ? "IDR" : "NON-IDR"));
400        if (picDisplayNumber != decPicture.picId)
401            DEBUG((", decoded pic %d", decPicture.picId));
402        if (decPicture.nbrOfErrMBs)
403        {
404            DEBUG((", concealed %d\n", decPicture.nbrOfErrMBs));
405        }
406        else
407            DEBUG(("\n"));
408        fflush(stdout);
409
410        numErrors += decPicture.nbrOfErrMBs;
411
412        /* Increment display number for every displayed picture */
413        picDisplayNumber++;
414
415        /* Write output picture to file */
416        imageData = (u8*)decPicture.pOutputPicture;
417        if (cropDisplay && decInfo.croppingFlag)
418        {
419            tmp = CropPicture(tmpImage, imageData,
420                decInfo.picWidth, decInfo.picHeight,
421                &decInfo.cropParams);
422            if (tmp)
423                return -1;
424            WriteOutput(outFileName, tmpImage, picSize);
425        }
426        else
427        {
428            WriteOutput(outFileName, imageData, picSize);
429        }
430    }
431
432#if RENDER
433        SDL_Quit();
434#endif
435
436    /* release decoder instance */
437    H264SwDecRelease(decInst);
438
439    if (foutput)
440        fclose(foutput);
441
442    /* free allocated buffers */
443    free(byteStrmStart);
444    free(tmpImage);
445
446    DEBUG(("Output file: %s\n", outFileName));
447
448    DEBUG(("DECODING DONE\n"));
449    if (numErrors || picDecodeNumber == 1)
450    {
451        DEBUG(("ERRORS FOUND\n"));
452        return 1;
453    }
454
455    return 0;
456}
457
458void paint(u8 *luma, u8 *cb, u8 *cr, int width, int height) {
459    int chromaWidth = width >> 1;
460    u32 *dst = (u32 *)screen->pixels;
461    int x, y = 0;
462    for (y = 0; y < height; y++) {
463        int lineOffLuma = y * width;
464        int lineOffChroma = (y >> 1) * chromaWidth;
465        for (x = 0; x < width; x++) {
466            int c = luma[lineOffLuma + x] - 16;
467            int d = cb[lineOffChroma + (x >> 1)] - 128;
468            int e = cr[lineOffChroma + (x >> 1)] - 128;
469
470            int red = (298 * c + 409 * e + 128) >> 8;
471            red = red < 0 ? 0 : (red > 255 ? 255 : red);
472            int green = (298 * c - 100 * d - 208 * e + 128) >> 8;
473            green = green < 0 ? 0 : (green > 255 ? 255 : green);
474            int blue = (298 * c + 516 * d + 128) >> 8;
475            blue = blue < 0 ? 0 : (blue > 255 ? 255 : blue);
476            int alpha = 255;
477            dst[lineOffLuma + x] = SDL_MapRGB(screen->format, red & 0xff, green & 0xff, blue & 0xff);
478        }
479    }
480}
481
482void DrawOutput(u8 *data, u32 picWidth, u32 picHeight) {
483    u32 size = picWidth * picHeight;
484    // paint(data, data + size, data + size + (size >> 2), picWidth, picHeight);
485}
486
487/*------------------------------------------------------------------------------
488
489    Function name:  WriteOutput
490
491    Purpose:
492        Write picture pointed by data to file. Size of the
493        picture in pixels is indicated by picSize.
494
495------------------------------------------------------------------------------*/
496void WriteOutput(char *filename, u8 *data, u32 picSize)
497{
498
499    /* foutput is global file pointer */
500    if (foutput == NULL)
501    {
502        /* open output file for writing, can be disabled with define.
503         * If file open fails -> exit */
504        if (strcmp(filename, "none") != 0)
505        {
506#if !defined(_NO_OUT)
507            foutput = fopen(filename, "wb");
508            if (foutput == NULL)
509            {
510                DEBUG(("UNABLE TO OPEN OUTPUT FILE\n"));
511                exit(100);
512            }
513#endif
514        }
515    }
516
517    if (foutput && data)
518        fwrite(data, 1, picSize, foutput);
519
520#if RENDER
521        SDL_UnlockSurface(screen);
522        SDL_Flip(screen);
523#endif
524}
525
526/*------------------------------------------------------------------------------
527
528    Function name: NextPacket
529
530    Purpose:
531        Get the pointer to start of next packet in input stream. Uses
532        global variables 'packetize' and 'nalUnitStream' to determine the
533        decoder input stream mode and 'streamStop' to determine the end
534        of stream. There are three possible stream modes:
535            default - the whole stream at once
536            packetize - a single NAL-unit with start code prefix
537            nalUnitStream - a single NAL-unit without start code prefix
538
539        pStrm stores pointer to the start of previous decoder input and is
540        replaced with pointer to the start of the next decoder input.
541
542        Returns the packet size in bytes
543
544------------------------------------------------------------------------------*/
545u32 NextPacket(u8 **pStrm)
546{
547
548    u32 index;
549    u32 maxIndex;
550    u32 zeroCount;
551    u8 *stream;
552    u8 byte;
553    static u32 prevIndex=0;
554
555    /* For default stream mode all the stream is in first packet */
556    if (!packetize && !nalUnitStream)
557        return 0;
558
559    index = 0;
560    stream = *pStrm + prevIndex;
561    maxIndex = (u32)(streamStop - stream);
562
563    if (maxIndex == 0)
564        return(0);
565
566    /* leading zeros of first NAL unit */
567    do
568    {
569        byte = stream[index++];
570    } while (byte != 1 && index < maxIndex);
571
572    /* invalid start code prefix */
573    if (index == maxIndex || index < 3)
574    {
575        DEBUG(("INVALID BYTE STREAM\n"));
576        exit(100);
577    }
578
579    /* nalUnitStream is without start code prefix */
580    if (nalUnitStream)
581    {
582        stream += index;
583        maxIndex -= index;
584        index = 0;
585    }
586
587    zeroCount = 0;
588
589    /* Search stream for next start code prefix */
590    /*lint -e(716) while(1) used consciously */
591    while (1)
592    {
593        byte = stream[index++];
594        if (!byte)
595            zeroCount++;
596
597        if ( (byte == 0x01) && (zeroCount >= 2) )
598        {
599            /* Start code prefix has two zeros
600             * Third zero is assumed to be leading zero of next packet
601             * Fourth and more zeros are assumed to be trailing zeros of this
602             * packet */
603            if (zeroCount > 3)
604            {
605                index -= 4;
606                zeroCount -= 3;
607            }
608            else
609            {
610                index -= zeroCount+1;
611                zeroCount = 0;
612            }
613            break;
614        }
615        else if (byte)
616            zeroCount = 0;
617
618        if (index == maxIndex)
619        {
620            break;
621        }
622
623    }
624
625    /* Store pointer to the beginning of the packet */
626    *pStrm = stream;
627    prevIndex = index;
628
629    /* nalUnitStream is without trailing zeros */
630    if (nalUnitStream)
631        index -= zeroCount;
632
633    return(index);
634
635}
636
637/*------------------------------------------------------------------------------
638
639    Function name: CropPicture
640
641    Purpose:
642        Perform cropping for picture. Input picture pInImage with dimensions
643        picWidth x picHeight is cropped with pCropParams and the resulting
644        picture is stored in pOutImage.
645
646------------------------------------------------------------------------------*/
647u32 CropPicture(u8 *pOutImage, u8 *pInImage,
648    u32 picWidth, u32 picHeight, CropParams *pCropParams)
649{
650
651    u32 i, j;
652    u32 outWidth, outHeight;
653    u8 *pOut, *pIn;
654
655    if (pOutImage == NULL || pInImage == NULL || pCropParams == NULL ||
656        !picWidth || !picHeight)
657    {
658        /* just to prevent lint warning, returning non-zero will result in
659         * return without freeing the memory */
660        free(pOutImage);
661        return(1);
662    }
663
664    if ( ((pCropParams->cropLeftOffset + pCropParams->cropOutWidth) >
665           picWidth ) ||
666         ((pCropParams->cropTopOffset + pCropParams->cropOutHeight) >
667           picHeight ) )
668    {
669        /* just to prevent lint warning, returning non-zero will result in
670         * return without freeing the memory */
671        free(pOutImage);
672        return(1);
673    }
674
675    outWidth = pCropParams->cropOutWidth;
676    outHeight = pCropParams->cropOutHeight;
677
678    /* Calculate starting pointer for luma */
679    pIn = pInImage + pCropParams->cropTopOffset*picWidth +
680        pCropParams->cropLeftOffset;
681    pOut = pOutImage;
682
683    /* Copy luma pixel values */
684    for (i = outHeight; i; i--)
685    {
686        for (j = outWidth; j; j--)
687        {
688            *pOut++ = *pIn++;
689        }
690        pIn += picWidth - outWidth;
691    }
692
693    outWidth >>= 1;
694    outHeight >>= 1;
695
696    /* Calculate starting pointer for cb */
697    pIn = pInImage + picWidth*picHeight +
698        pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
699
700    /* Copy cb pixel values */
701    for (i = outHeight; i; i--)
702    {
703        for (j = outWidth; j; j--)
704        {
705            *pOut++ = *pIn++;
706        }
707        pIn += picWidth/2 - outWidth;
708    }
709
710    /* Calculate starting pointer for cr */
711    pIn = pInImage + 5*picWidth*picHeight/4 +
712        pCropParams->cropTopOffset*picWidth/4 + pCropParams->cropLeftOffset/2;
713
714    /* Copy cr pixel values */
715    for (i = outHeight; i; i--)
716    {
717        for (j = outWidth; j; j--)
718        {
719            *pOut++ = *pIn++;
720        }
721        pIn += picWidth/2 - outWidth;
722    }
723
724    return (0);
725}
726
727/*------------------------------------------------------------------------------
728
729    Function name:  H264SwDecTrace
730
731    Purpose:
732        Example implementation of H264SwDecTrace function. Prototype of this
733        function is given in H264SwDecApi.h. This implementation appends
734        trace messages to file named 'dec_api.trc'.
735
736------------------------------------------------------------------------------*/
737void H264SwDecTrace(char *string)
738{
739    FILE *fp;
740
741    fp = fopen("dec_api.trc", "at");
742
743    if (!fp)
744        return;
745
746    fwrite(string, 1, strlen(string), fp);
747    fwrite("\n", 1,1, fp);
748
749    fclose(fp);
750}
751
752/*------------------------------------------------------------------------------
753
754    Function name:  H264SwDecMalloc
755
756    Purpose:
757        Example implementation of H264SwDecMalloc function. Prototype of this
758        function is given in H264SwDecApi.h. This implementation uses
759        library function malloc for allocation of memory.
760
761------------------------------------------------------------------------------*/
762void* H264SwDecMalloc(u32 size)
763{
764
765#if defined(CHECK_MEMORY_USAGE)
766    /* Note that if the decoder has to free and reallocate some of the buffers
767     * the total value will be invalid */
768    static u32 numBytes = 0;
769    numBytes += size;
770    DEBUG(("Allocated %d bytes, total %d\n", size, numBytes));
771#endif
772
773    return malloc(size);
774}
775
776/*------------------------------------------------------------------------------
777
778    Function name:  H264SwDecFree
779
780    Purpose:
781        Example implementation of H264SwDecFree function. Prototype of this
782        function is given in H264SwDecApi.h. This implementation uses
783        library function free for freeing of memory.
784
785------------------------------------------------------------------------------*/
786void H264SwDecFree(void *ptr)
787{
788    free(ptr);
789}
790
791/*------------------------------------------------------------------------------
792
793    Function name:  H264SwDecMemcpy
794
795    Purpose:
796        Example implementation of H264SwDecMemcpy function. Prototype of this
797        function is given in H264SwDecApi.h. This implementation uses
798        library function memcpy to copy src to dest.
799
800------------------------------------------------------------------------------*/
801void H264SwDecMemcpy(void *dest, void *src, u32 count)
802{
803    memcpy(dest, src, count);
804}
805
806/*------------------------------------------------------------------------------
807
808    Function name:  H264SwDecMemset
809
810    Purpose:
811        Example implementation of H264SwDecMemset function. Prototype of this
812        function is given in H264SwDecApi.h. This implementation uses
813        library function memset to set content of memory area pointed by ptr.
814
815------------------------------------------------------------------------------*/
816void H264SwDecMemset(void *ptr, i32 value, u32 count)
817{
818    memset(ptr, value, count);
819}
820