Beispiel #1
0
SoftAVC::~SoftAVC() {
    H264SwDecRelease(mHandle);
    mHandle = NULL;

    while (mPicToHeaderMap.size() != 0) {
        OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.editValueAt(0);
        mPicToHeaderMap.removeItemsAt(0);
        delete header;
        header = NULL;
    }
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
    List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
    CHECK(outQueue.empty());
    CHECK(inQueue.empty());

    delete[] mFirstPicture;
}
MEDIA_STATUS_CODE VideoH264DecClose(void)
{
    drv_trace0(TRACE_GROUP_10,OPEN_API_ENTERVIDEOH264DECCLOSE);
    VideoH264DecOutputPic((kal_uint32)H264SW_OPENAPI_EOF);

    if ( rH264SwCtrl.fgIsCodecInit == KAL_TRUE )
    {
        drv_trace0(TRACE_GROUP_8, H264DEC_DEINIT);
        H264SwDecRelease(rH264SwCtrl.prH264DecInst);
    }

    drv_trace0(TRACE_GROUP_8, H264DEC_CLOSE);
    if (rH264SwCtrl.pAdmId)
    {
        kal_adm_delete(rH264SwCtrl.pAdmId);
        rH264SwCtrl.pAdmId = NULL;
    }
    rH264SwCtrl.fgBsBufferCacheable = KAL_FALSE;
    rH264SwCtrl.fgFrmBufferCacheable = KAL_FALSE;
    rH264SwCtrl.fgFrmBufferSwitch = KAL_FALSE;
    rH264SwCtrl.fgIsCodecInit = KAL_FALSE;
    rH264SwCtrl.u2FrameHeight = 0;
    rH264SwCtrl.u2FrameWidth = 0;
    rH264SwCtrl.u2RealHeight = 0;
    rH264SwCtrl.u2RealWidth = 0;
    rH264SwCtrl.u4BufferSize = 0;
    rH264SwCtrl.pfnSetFrameUnReference = NULL;
    rH264SwCtrl.pfnOutputOneFrame = NULL;
    rH264SwCtrl.pfnGetYUVBuffer = NULL;

#if defined(__MTK_TARGET__)
#if defined(MT6236) || defined(MT6236B)
    DCM_Unload(DYNAMIC_CODE_264DEC_S);
#endif
#endif
    return MEDIA_STATUS_OK;
}
/*------------------------------------------------------------------------------

------------------------------------------------------------------------------*/
int main(int argc, char **argv)
{

    i32 instCount, instRunning;
    i32 i;
    u32 maxNumPics;
    u32 strmLen;
    H264SwDecRet ret;
    u32 numErrors = 0;
    u32 cropDisplay = 0;
    u32 disableOutputReordering = 0;
    FILE *finput;
    Decoder **decoder;
    char outFileName[256] = "out.yuv";


    if ( argc > 1 && strcmp(argv[1], "-T") == 0 )
    {
        fprintf(stderr, "%s\n", tagName);
        return 0;
    }

    if (argc < 2)
    {
        DEBUG((
            "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file1.264 [file2.264] .. [fileN.264]\n",
            argv[0]));
        DEBUG(("\t-Nn forces decoding to stop after n pictures\n"));
#if defined(_NO_OUT)
        DEBUG(("\t-Ooutfile output writing disabled at compile time\n"));
#else
        DEBUG(("\t-Ooutfile write output to \"outfile\" (default out.yuv)\n"));
        DEBUG(("\t-Onone does not write output\n"));
#endif
        DEBUG(("\t-C display cropped image (default decoded image)\n"));
        DEBUG(("\t-R disable DPB output reordering\n"));
        DEBUG(("\t-T to print tag name and exit\n"));
        exit(100);
    }

    instCount = argc - 1;

    /* read command line arguments */
    maxNumPics = 0;
    for (i = 1; i < (argc-1); i++)
    {
        if ( strncmp(argv[i], "-N", 2) == 0 )
        {
            maxNumPics = (u32)atoi(argv[i]+2);
            instCount--;
        }
        else if ( strncmp(argv[i], "-O", 2) == 0 )
        {
            strcpy(outFileName, argv[i]+2);
            instCount--;
        }
        else if ( strcmp(argv[i], "-C") == 0 )
        {
            cropDisplay = 1;
            instCount--;
        }
        else if ( strcmp(argv[i], "-R") == 0 )
        {
            disableOutputReordering = 1;
            instCount--;
        }
    }

    if (instCount < 1)
    {
        DEBUG(("No input files\n"));
        exit(100);
    }

    /* allocate memory for multiple decoder instances
     * one instance for every stream file */
    decoder = (Decoder **)malloc(sizeof(Decoder*)*(u32)instCount);
    if (decoder == NULL)
    {
        DEBUG(("Unable to allocate memory\n"));
        exit(100);
    }

    /* prepare each decoder instance */
    for (i = 0; i < instCount; i++)
    {
        decoder[i] = (Decoder *)calloc(1, sizeof(Decoder));

        /* open input file */
        finput = fopen(argv[argc-instCount+i],"rb");
        if (finput == NULL)
        {
            DEBUG(("Unable to open input file <%s>\n", argv[argc-instCount+i]));
            exit(100);
        }

        DEBUG(("Reading input file[%d] %s\n", i, argv[argc-instCount+i]));

        /* read input stream to buffer */
        fseek(finput,0L,SEEK_END);
        strmLen = (u32)ftell(finput);
        rewind(finput);
        decoder[i]->byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen);
        if (decoder[i]->byteStrmStart == NULL)
        {
            DEBUG(("Unable to allocate memory\n"));
            exit(100);
        }
        fread(decoder[i]->byteStrmStart, sizeof(u8), strmLen, finput);
        fclose(finput);

        /* open output file */
        if (strcmp(outFileName, "none") != 0)
        {
#if defined(_NO_OUT)
            decoder[i]->foutput = NULL;
#else
            sprintf(decoder[i]->outFileName, "%s%i", outFileName, i);
            decoder[i]->foutput = fopen(decoder[i]->outFileName, "wb");
            if (decoder[i]->foutput == NULL)
            {
                DEBUG(("Unable to open output file\n"));
                exit(100);
            }
#endif
        }

        ret = H264SwDecInit(&(decoder[i]->decInst), disableOutputReordering);

        if (ret != H264SWDEC_OK)
        {
            DEBUG(("Init failed %d\n", ret));
            exit(100);
        }

        decoder[i]->decInput.pStream = decoder[i]->byteStrmStart;
        decoder[i]->decInput.dataLen = strmLen;
        decoder[i]->decInput.intraConcealmentMethod = 0;

    }

    /* main decoding loop */
    do
    {
        /* decode once using each instance */
        for (i = 0; i < instCount; i++)
        {
            ret = H264SwDecDecode(decoder[i]->decInst,
                                &(decoder[i]->decInput),
                                &(decoder[i]->decOutput));

            switch(ret)
            {

                case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:

                    ret = H264SwDecGetInfo(decoder[i]->decInst,
                            &(decoder[i]->decInfo));
                    if (ret != H264SWDEC_OK)
                        exit(1);

                    if (cropDisplay && decoder[i]->decInfo.croppingFlag)
                    {
                        DEBUG(("Decoder[%d] Cropping params: (%d, %d) %dx%d\n",
                            i,
                            decoder[i]->decInfo.cropParams.cropLeftOffset,
                            decoder[i]->decInfo.cropParams.cropTopOffset,
                            decoder[i]->decInfo.cropParams.cropOutWidth,
                            decoder[i]->decInfo.cropParams.cropOutHeight));
                    }

                    DEBUG(("Decoder[%d] Width %d Height %d\n", i,
                        decoder[i]->decInfo.picWidth,
                        decoder[i]->decInfo.picHeight));

                    DEBUG(("Decoder[%d] videoRange %d, matricCoefficients %d\n",
                        i, decoder[i]->decInfo.videoRange,
                        decoder[i]->decInfo.matrixCoefficients));
                    decoder[i]->decInput.dataLen -=
                        (u32)(decoder[i]->decOutput.pStrmCurrPos -
                              decoder[i]->decInput.pStream);
                    decoder[i]->decInput.pStream =
                        decoder[i]->decOutput.pStrmCurrPos;
                    break;

                case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
                    decoder[i]->decInput.dataLen -=
                        (u32)(decoder[i]->decOutput.pStrmCurrPos -
                              decoder[i]->decInput.pStream);
                    decoder[i]->decInput.pStream =
                        decoder[i]->decOutput.pStrmCurrPos;
                    /* fall through */
                case H264SWDEC_PIC_RDY:
                    if (ret == H264SWDEC_PIC_RDY)
                        decoder[i]->decInput.dataLen = 0;

                    ret = H264SwDecGetInfo(decoder[i]->decInst,
                            &(decoder[i]->decInfo));
                    if (ret != H264SWDEC_OK)
                        exit(1);

                    while (H264SwDecNextPicture(decoder[i]->decInst,
                            &(decoder[i]->decPicture), 0) == H264SWDEC_PIC_RDY)
                    {
                        decoder[i]->picNumber++;

                        numErrors += decoder[i]->decPicture.nbrOfErrMBs;

                        DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n",
                            i, decoder[i]->picNumber,
                            decoder[i]->decPicture.isIdrPicture
                                ? "IDR" : "NON-IDR",
                            decoder[i]->decPicture.nbrOfErrMBs));
                        fflush(stdout);

                        CropWriteOutput(decoder[i]->foutput,
                                (u8*)decoder[i]->decPicture.pOutputPicture,
                                cropDisplay, &(decoder[i]->decInfo));
                    }

                    if (maxNumPics && decoder[i]->picNumber == maxNumPics)
                        decoder[i]->decInput.dataLen = 0;
                    break;

                case H264SWDEC_STRM_PROCESSED:
                case H264SWDEC_STRM_ERR:
                case H264SWDEC_PARAM_ERR:
                    decoder[i]->decInput.dataLen = 0;
                    break;

                default:
                    DEBUG(("Decoder[%d] FATAL ERROR\n", i));
                    exit(10);
                    break;

            }
        }

        /* check if any of the instances is still running (=has more data) */
        instRunning = instCount;
        for (i = 0; i < instCount; i++)
        {
            if (decoder[i]->decInput.dataLen == 0)
                instRunning--;
        }

    } while (instRunning);


    /* get last frames and close each instance */
    for (i = 0; i < instCount; i++)
    {
        while (H264SwDecNextPicture(decoder[i]->decInst,
                &(decoder[i]->decPicture), 1) == H264SWDEC_PIC_RDY)
        {
            decoder[i]->picNumber++;

            DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n",
                i, decoder[i]->picNumber,
                decoder[i]->decPicture.isIdrPicture
                    ? "IDR" : "NON-IDR",
                decoder[i]->decPicture.nbrOfErrMBs));
            fflush(stdout);

            CropWriteOutput(decoder[i]->foutput,
                    (u8*)decoder[i]->decPicture.pOutputPicture,
                    cropDisplay, &(decoder[i]->decInfo));
        }

        H264SwDecRelease(decoder[i]->decInst);

        if (decoder[i]->foutput)
            fclose(decoder[i]->foutput);

        free(decoder[i]->byteStrmStart);

        free(decoder[i]);
    }

    free(decoder);

    if (numErrors)
        return 1;
    else
        return 0;

}
/*------------------------------------------------------------------------------

    Function name:  main

    Purpose:
        main function. Assuming that executable is named 'decoder' the usage
        is as follows

            decoder inputFileName

        , where inputFileName shall be name of file containing h264 stream
        data.

------------------------------------------------------------------------------*/
int main(int argc, char **argv)
{

    u8 *byteStrmStart;
    u8 *byteStrm;
    u32 strmLen;
    u32 picSize;
    H264SwDecInst decInst;
    H264SwDecRet ret;
    H264SwDecInput decInput;
    H264SwDecOutput decOutput;
    H264SwDecPicture decPicture;
    H264SwDecInfo decInfo;
    u32 picNumber;

    FILE *finput;
    FILE *foutput;

    /* Check that enough command line arguments given, if not -> print usage
     * information out */
    if (argc < 2)
    {
        printf( "Usage: %s file.h264\n", argv[0]);
        return -1;
    }

    /* open output file for writing, output file named out.yuv. If file open
     * fails -> exit */
    foutput = fopen("out.yuv", "wb");
    if (foutput == NULL)
    {
        printf("UNABLE TO OPEN OUTPUT FILE\n");
        return -1;
    }

    /* open input file for reading, file name given by user. If file open
     * fails -> exit */
    finput = fopen(argv[argc-1], "rb");
    if (finput == NULL)
    {
        printf("UNABLE TO OPEN INPUT FILE\n");
        return -1;
    }

    /* check size of the input file -> length of the stream in bytes */
    fseek(finput, 0L, SEEK_END);
    strmLen = (u32)ftell(finput);
    rewind(finput);

    /* allocate memory for stream buffer, exit if unsuccessful */
    byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8), strmLen);
    if (byteStrm == NULL)
    {
        printf("UNABLE TO ALLOCATE MEMORY\n");
        return -1;
    }

    /* read input stream from file to buffer and close input file */
    fread(byteStrm, sizeof(u8), strmLen, finput);
    fclose(finput);

    /* initialize decoder. If unsuccessful -> exit */
    ret = H264SwDecInit(&decInst, 0);
    if (ret != H264SWDEC_OK)
    {
        printf("DECODER INITIALIZATION FAILED\n");
        return -1;
    }

    /* initialize H264SwDecDecode() input structure */
    decInput.pStream = byteStrmStart;
    decInput.dataLen = strmLen;
    decInput.intraConcealmentMethod = 0;

    picNumber = 0;

    /* For performance measurements, read the start time (in seconds) here.
     * The decoding time should be measured over several frames and after
     * that average fps (frames/second) can be calculated.
     *
     * startTime = GetTime();
     *
     * To prevent calculating file I/O latensies as a decoding time,
     * comment out WriteOutput function call. Also prints to stdout might
     * consume considerable amount of cycles during measurement */

    /* main decoding loop */
    do
    {
        /* call API function to perform decoding */
        ret = H264SwDecDecode(decInst, &decInput, &decOutput);

        switch(ret)
        {

            case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:

                /* picture dimensions are available for query now */
                ret = H264SwDecGetInfo(decInst, &decInfo);
                if (ret != H264SWDEC_OK)
                    return -1;

                /* picture size in pixels */
                picSize = decInfo.picWidth * decInfo.picHeight;
                /* memory needed for YCbCr 4:2:0 picture in bytes */
                picSize = (3 * picSize)/2;
                /* memory needed for 16-bit RGB picture in bytes
                 * picSize = (decInfo.picWidth * decInfo.picHeight) * 2; */

                printf("Width %d Height %d\n",
                    decInfo.picWidth, decInfo.picHeight);

                /* update H264SwDecDecode() input structure, number of bytes
                 * "consumed" is computed as difference between the new stream
                 * pointer and old stream pointer */
                decInput.dataLen -=
                    (u32)(decOutput.pStrmCurrPos - decInput.pStream);
                decInput.pStream = decOutput.pStrmCurrPos;
                break;

            case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY:
            case H264SWDEC_PIC_RDY:

                /* update H264SwDecDecode() input structure, number of bytes
                 * "consumed" is computed as difference between the new stream
                 * pointer and old stream pointer */
                decInput.dataLen -=
                    (u32)(decOutput.pStrmCurrPos - decInput.pStream);
                decInput.pStream = decOutput.pStrmCurrPos;

                /* use function H264SwDecNextPicture() to obtain next picture
                 * in display order. Function is called until no more images
                 * are ready for display */
                while (H264SwDecNextPicture(decInst, &decPicture, 0) ==
                    H264SWDEC_PIC_RDY) { picNumber++;

                    printf("PIC %d, type %s, concealed %d\n", picNumber,
                        decPicture.isIdrPicture ? "IDR" : "NON-IDR",
                        decPicture.nbrOfErrMBs);
                    fflush(stdout);

                    /* Do color conversion if needed to get display image
                     * in RGB-format
                     *
                     * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */

                    /* write next display image to output file */
                    WriteOutput(foutput, (u8*)decPicture.pOutputPicture,
                        picSize);
                }

                break;

            case H264SWDEC_EVALUATION_LIMIT_EXCEEDED:
                /* evaluation version of the decoder has limited decoding
                 * capabilities */
                printf("EVALUATION LIMIT REACHED\n");
                goto end;

            default:
                printf("UNRECOVERABLE ERROR\n");
                return -1;
        }
    /* keep decoding until all data from input stream buffer consumed */
    } while (decInput.dataLen > 0);

end:

    /* if output in display order is preferred, the decoder shall be forced
     * to output pictures remaining in decoded picture buffer. Use function
     * H264SwDecNextPicture() to obtain next picture in display order. Function
     * is called until no more images are ready for display. Second parameter
     * for the function is set to '1' to indicate that this is end of the
     * stream and all pictures shall be output */
    while (H264SwDecNextPicture(decInst, &decPicture, 1) ==
        H264SWDEC_PIC_RDY) {

        picNumber++;

        printf("PIC %d, type %s, concealed %d\n", picNumber,
            decPicture.isIdrPicture ? "IDR" : "NON-IDR",
            decPicture.nbrOfErrMBs);
        fflush(stdout);

        /* Do color conversion if needed to get display image
         * in RGB-format
         *
         * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */

        /* write next display image to output file */
        WriteOutput(foutput, (u8*)decPicture.pOutputPicture, picSize);
    }

    /* For performance measurements, read the end time (in seconds) here.
     *
     * endTime = GetTime();
     *
     * Now the performance can be calculated as frames per second:
     * fps = picNumber / (endTime - startTime); */


    /* release decoder instance */
    H264SwDecRelease(decInst);

    /* close output file */
    fclose(foutput);

    /* free byte stream buffer */
    free(byteStrmStart);

    return 0;

}