/*
 *  ======== analyze ========
 */
static Void analyze(VIDANALYTICS_Handle analyzer, FILE *in, FILE *out)
{
    Int                         n;
    Int32                       result;

    VIDANALYTICS_InArgs         inArgs;
    VIDANALYTICS_OutArgs        outArgs;
    VIDANALYTICS_DynamicParams  dynParams;
    VIDANALYTICS_Status         status;

    XDM1_BufDesc                inBufDesc;
    XDM1_BufDesc                outBufDesc;

    /* clear and initialize the buffer descriptors */
    inBufDesc.numBufs = outBufDesc.numBufs = 1;

    inBufDesc.descs[0].bufSize = outBufDesc.descs[0].bufSize = NSAMPLES;

    inBufDesc.descs[0].buf = inBuf;
    outBufDesc.descs[0].buf = outBuf;

    /* initialize all "sized" fields */
    inArgs.size    = sizeof(inArgs);
    outArgs.size   = sizeof(outArgs);
    dynParams.size = sizeof(dynParams);
    status.size    = sizeof(status);

    /* if the codecs support it, dump their versions */
    status.data.numBufs = 1;
    status.data.descs[0].buf = versionBuf;
    status.data.descs[0].bufSize = MAXVERSIONSIZE;

    result = VIDANALYTICS_control(analyzer, XDM_GETVERSION, &dynParams,
        &status);
    GT_1trace(curMask, GT_1CLASS, "Analyzer version:  %s\n",
        (result == VIDANALYTICS_EOK ?
            ((char *)status.data.descs[0].buf) : "[unknown]"));

    /*
     * This app expects the analyzer to accept 1 buf in and provide 1 buf out,
     * and the buf sizes of the in and out buffer must be able to handle
     * NSAMPLES bytes of data.
     */
    status.data.numBufs = 0;
    status.data.descs[0].buf = NULL;
    result = VIDANALYTICS_control(analyzer, XDM_GETBUFINFO, &dynParams,
        &status);
    if (result != VIDANALYTICS_EOK) {
        /* failure, report error and exit */
        GT_1trace(curMask, GT_7CLASS, "VIDANALYTICS control status = %ld\n",
            status);
        return;
    }

    /* Validate this analyzer will meet our buffer requirements */
    if ((inBufDesc.numBufs < status.bufInfo.minNumInBufs) ||
        (IFRAMESIZE < status.bufInfo.minInBufSize[0]) ||
        (outBufDesc.numBufs < status.bufInfo.minNumOutBufs) ||
        (OFRAMESIZE < status.bufInfo.minOutBufSize[0])) {

        /* failure, report error and exit */
        GT_0trace(curMask, GT_7CLASS,
            "Error:  analyzer codec feature conflict\n");
        return;
    }

    /*
     * Read complete frames from in, analyze, and write to out.
     */
    for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) {

#ifdef CACHE_ENABLED
#ifdef xdc_target__isaCompatible_64P
        /*
         *  fread() on this processor is implemented using CCS's stdio, which
         *  is known to write into the cache, not physical memory.  To meet
         *  xDAIS DMA Rule 7, we must writeback the cache into physical
         *  memory.  Also, per DMA Rule 7, we must invalidate the buffer's
         *  cache before providing it to any xDAIS algorithm.
         */
        Memory_cacheWbInv(inBuf, IFRAMESIZE);
#else
#error Unvalidated config - add appropriate fread-related cache maintenance
#endif
        /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
        Memory_cacheInv(outBuf, OFRAMESIZE);
#endif

        GT_1trace(curMask, GT_1CLASS, "App-> Processing frame %d...\n", n);

        /*
         * Analyze the frame.
         */
        result = VIDANALYTICS_process(analyzer, &inBufDesc, &outBufDesc,
            &inArgs, &outArgs);

        GT_2trace(curMask, GT_2CLASS,
            "App-> Analyzer frame %d process returned - 0x%x)\n", n, result);

        if (result != VIDANALYTICS_EOK) {
            GT_3trace(curMask, GT_7CLASS,
                "App-> Analyzer frame %d processing FAILED, result = 0x%x, "
                "extendedError = 0x%x\n", n, result, outArgs.extendedError);
            break;
        }

#ifdef CACHE_ENABLED
        /*
         * Conditionally writeback the analyzed buf from the previous
         * call.
         */
        if (XDM_ISACCESSMODE_WRITE(outBufDesc.descs[0].accessMask)) {
            Memory_cacheWb(outBuf, OFRAMESIZE);
        }
#endif

        /* write to file */
        fwrite(outBufDesc.descs[0].buf, OFRAMESIZE, 1, out);
    }

    GT_1trace(curMask, GT_1CLASS, "%d frames analyzed\n", n);
}
Exemplo n.º 2
0
/*
 *  ======== call ========
 */
static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg)
{
    _VIDANALYTICS_Msg *msg  = (_VIDANALYTICS_Msg *)visaMsg;
    VIDANALYTICS_Handle handle = (VIDANALYTICS_Handle)visaHandle;
    Int i;
    XDM1_BufDesc inBufs;
    XDM1_BufDesc outBufs;
    IVIDANALYTICS_OutArgs *pOutArgs;
    IVIDANALYTICS_Status *pStatus;
    Int numBufs;

    /* perform the requested VIDANALYTICS operation by parsing message. */
    switch (msg->visa.cmd) {

        case _VIDANALYTICS_CPROCESS: {
            /* unmarshal inBufs and outBufs */
            inBufs           = msg->cmd.process.inBufs;
            outBufs          = msg->cmd.process.outBufs;

            if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) {
                /* invalidate cache for all input buffers */
                for (i = 0, numBufs = 0; (numBufs < inBufs.numBufs) &&
                         (i < XDM_MAX_IO_BUFFERS); i++) {
                    if (inBufs.descs[i].buf != NULL) {
                        /* valid member of sparse array, manage it */
                        Memory_cacheInv(inBufs.descs[i].buf,
                                inBufs.descs[i].bufSize);

                        if (++numBufs == inBufs.numBufs) {
                            break;
                        }
                    }
                }

                /* invalidate cache for all output buffers */
                for (i = 0, numBufs = 0; (numBufs < outBufs.numBufs) &&
                         (i < XDM_MAX_IO_BUFFERS); i++) {
                    if (outBufs.descs[i].buf != NULL) {
                        /* valid member of sparse array, manage it */
                        Memory_cacheInv(outBufs.descs[i].buf,
                                outBufs.descs[i].bufSize);

                        if (++numBufs == outBufs.numBufs) {
                            break;
                        }
                    }
                }
            } /* SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB */

            /* unmarshall outArgs based on the "size" of inArgs */
            pOutArgs =
                (IVIDANALYTICS_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
                    msg->cmd.process.inArgs.size);

            /*
             * Note, there's no need to invalidate cache for
             * pOutArgs->encodedBuf bufs as they're
             * not _really_ OUT buffers.  Rather they're references to
             * the _real_ OUT buffers that are provided in outBufs - which
             * were already invalidated above.
             */

            /* make the process call */
            msg->visa.status = VIDANALYTICS_process(handle,
                &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs);

            if (SKEL_cachingPolicy == SKEL_WBINVALL) {
                Memory_cacheWbInvAll();
            }
            else if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) {
                /* writeback cache for analysis output buffers  */
                for (i = 0, numBufs = 0; (numBufs < outBufs.numBufs) &&
                         (i < XDM_MAX_IO_BUFFERS); i++) {
                    if ((outBufs.descs[i].buf != NULL) &&
                            XDM_ISACCESSMODE_WRITE(outBufs.descs[i].accessMask)) {

                        /* valid member of sparse array, written to via CPU */
                        Memory_cacheWb(outBufs.descs[i].buf,
                                outBufs.descs[i].bufSize);

                        /*
                         * Since we've cacheWb this buffer, we arguably should
                         * reflect this cache state and clear the WRITE bit in
                         * the .accessMask field.  However, we know the stub
                         * doesn't propogate this field to the calling app, so
                         * this extra buffer management detail isn't necessary:
                         *
                         * XDM_CLEARACCESSMODE_WRITE(outBufs.descs[i].accessMask);
                         */

                        if (++numBufs == outBufs.numBufs) {
                            break;
                        }
                    }
                }
            }

            /*
             * Note that any changes to individual outBufs[i] values made by
             * the codec will automatically update msg->cmd.process.outBufs
             * as we pass the outBufs array by reference.
             */

            break;
        }

        case _VIDANALYTICS_CCONTROL: {
            /* unmarshall status based on the "size" of dynParams */
            pStatus =
                (IVIDANALYTICS_Status *)((UInt)(&(msg->cmd.control.dynParams)) +
                msg->cmd.control.dynParams.size);

            /* invalidate data buffers */
            for (i = 0, numBufs = 0; (numBufs < pStatus->data.numBufs) &&
                    (i < XDM_MAX_IO_BUFFERS); i++) {
                if (pStatus->data.descs[i].buf != NULL) {
                    /* valid member of sparse array, manage it */
                    Memory_cacheInv(pStatus->data.descs[i].buf,
                        pStatus->data.descs[i].bufSize);

                    if (++numBufs == pStatus->data.numBufs) {
                        break;
                    }
                }
            }

            msg->visa.status = VIDANALYTICS_control(handle, msg->cmd.control.id,
                &(msg->cmd.control.dynParams), pStatus);

            /* writeback data buffers */
            for (i = 0, numBufs = 0; (numBufs < pStatus->data.numBufs) &&
                    (i < XDM_MAX_IO_BUFFERS); i++) {
                if ((pStatus->data.descs[i].buf != NULL) &&
                    XDM_ISACCESSMODE_WRITE(pStatus->data.descs[i].accessMask)) {

                    /* valid member of sparse array, manage it */
                    Memory_cacheWb(pStatus->data.descs[i].buf,
                        pStatus->data.descs[i].bufSize);

                    /*
                     * Since we've cacheWb this buffer, we arguably should
                     * reflect this cache state and clear the WRITE bit in
                     * the .accessMask field.  However, we know the stub
                     * doesn't propogate this field to the calling app, so
                     * this extra buffer management detail isn't necessary:
                     *
                     * XDM_CLEARACCESSMODE_WRITE(
                     *         pStatus->data.descs[i].accessMask);
                     */

                    if (++numBufs == pStatus->data.numBufs) {
                        break;
                    }
                }
            }

            break;
        }

        default: {
            msg->visa.status = VISA_EFAIL;

            break;
        }
    }
    return (VISA_EOK);
}