Example #1
0
/******************************************************************************
 * gst_tiprepencbuf_convert_gst_to_dmai
 *  This function convert gstreamer buffer into DMAI graphics buffer.
 *****************************************************************************/
static Buffer_Handle
gst_tiprepencbuf_convert_gst_to_dmai(GstTIPrepEncBuf * prepencbuf,
    GstBuffer * buf, gboolean reference)
{
    BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
    Buffer_Handle   hBuf     = NULL;

    gfxAttrs.bAttrs.reference = reference;
    gfxAttrs.dim.width        = prepencbuf->srcWidth;
    gfxAttrs.dim.height       = prepencbuf->srcHeight;
    gfxAttrs.colorSpace       = prepencbuf->srcColorSpace;
    gfxAttrs.dim.lineLength   = BufferGfx_calcLineLength(gfxAttrs.dim.width,
                                    prepencbuf->srcColorSpace);

    hBuf = Buffer_create(GST_BUFFER_SIZE(buf),
        BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hBuf == NULL) {
        GST_ERROR("failed to create  buffer\n");
        return NULL;
    }
    Buffer_setUserPtr(hBuf, (Int8 *) GST_BUFFER_DATA(buf));
    Buffer_setNumBytesUsed(hBuf, GST_BUFFER_SIZE(buf));
    return hBuf;
}
Example #2
0
static gboolean
alloc_bufTab(GstTICaptureSrc *src)
{
    BufferGfx_Attrs gfx  = BufferGfx_Attrs_DEFAULT;
    int size;

    gfx.dim.width = src->width;
    gfx.dim.height = src->height;
    gfx.colorSpace = src->cAttrs.colorSpace;

    gfx.dim.lineLength = BufferGfx_calcLineLength(src->width, gfx.colorSpace);

    #if defined(Platform_dm365) || defined(Platform_dm368)
        gfx.dim.lineLength = Dmai_roundUp(gfx.dim.lineLength, 32);
    #endif

    size = gst_ti_calc_buffer_size(gfx.dim.width, gfx.dim.height, gfx.dim.lineLength, gfx.colorSpace);
		GST_INFO(
				"bufsize: %d %ldx%ld linesize %ld", 
				size,
				gfx.dim.width, gfx.dim.height, gfx.dim.lineLength 
				);

    gfx.bAttrs.useMask = gst_tidmaibuffer_VIDEOSRC_FREE;
    src->cAttrs.numBufs = src->numbufs;
    src->hBufTab = gst_tidmaibuftab_new(src->cAttrs.numBufs, size,
        BufferGfx_getBufferAttrs(&gfx));
    gst_tidmaibuftab_set_blocking(src->hBufTab, FALSE);

    return TRUE;
}
Example #3
0
/******************************************************************************
 * Buffer_clone
 ******************************************************************************/
Buffer_Handle Buffer_clone(Buffer_Handle hBuf)
{
    BufferGfx_Attrs     gfxAttrs = BufferGfx_Attrs_DEFAULT;
    Buffer_Handle       hNewBuf;

    Buffer_getAttrs(hBuf, BufferGfx_getBufferAttrs(&gfxAttrs));

    hNewBuf = Buffer_create(hBuf->origState.numBytes,
                            BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hNewBuf == NULL) {
        Dmai_err0("Failed to create new Buffer while cloning\n");
        return NULL;
    }

    return hNewBuf;
}
Example #4
0
/******************************************************************************
 * captureThrFxn
 ******************************************************************************/
Void *captureThrFxn(Void *arg)
{
    CaptureEnv          *envp           = (CaptureEnv *) arg;
    Void                *status         = THREAD_SUCCESS;
    Capture_Attrs        cAttrs         = Capture_Attrs_DM365_DEFAULT;
    BufferGfx_Attrs      gfxAttrs       = BufferGfx_Attrs_DEFAULT;
    Capture_Handle       hCapture       = NULL;
    BufTab_Handle        hBufTab        = NULL;
    BufferGfx_Dimensions dim;
    Buffer_Handle        hDstBuf, hCapBuf;
    Int32                width, height, bufSize;
    Int                  fifoRet;
    ColorSpace_Type      colorSpace = ColorSpace_YUV420PSEMI;

    /* Create capture device driver instance */
    cAttrs.numBufs = NUM_CAPTURE_BUFS;
    cAttrs.videoInput = envp->videoInput;    
    cAttrs.videoStd   = envp->videoStd;
    cAttrs.colorSpace = colorSpace;

    if (VideoStd_getResolution(envp->videoStd, &width, &height) < 0) {
        ERR("Failed to calculate resolution of video standard\n");
        cleanup(THREAD_FAILURE);
    }

    if (envp->imageWidth > 0 && envp->imageHeight > 0) {
        if (width < envp->imageWidth && height < envp->imageHeight) {
            ERR("User resolution (%ldx%ld) larger than detected (%ldx%ld)\n",
                envp->imageWidth, envp->imageHeight, width, height);
            cleanup(THREAD_FAILURE);
        }

       /*
        * Capture driver provides 32-byte aligned data. We 32-byte align the
        * capture and video buffers to perform zero copy encoding.
        */
        envp->imageWidth = Dmai_roundUp(envp->imageWidth, 32);
    }
    else {
        /* Resolution was not set on command line. Set to defaults. */
        envp->imageHeight = height;

       /*
        * Capture driver provides 32-byte aligned data. We 32-byte align the
        * capture and video buffers to perform zero copy encoding.
        */
        envp->imageWidth  = Dmai_roundUp(width, 32); 
    }

    Dmai_clear(dim);
    dim.width      = envp->imageWidth;
    dim.height     = envp->imageHeight;

    dim.lineLength = Dmai_roundUp(dim.width, 32);
    if (colorSpace ==  ColorSpace_YUV420PSEMI) {
        bufSize = dim.lineLength * dim.height * 3 / 2;
    } else {
        bufSize = dim.lineLength * dim.height * 2;
    }
    gfxAttrs.dim = dim;

    /* Report the video standard and image size back to the main thread */
    Rendezvous_meet(envp->hRendezvousCapStd);

    gfxAttrs.colorSpace = colorSpace;
    hBufTab = BufTab_create(NUM_CAPTURE_BUFS, bufSize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));
    if (hBufTab == NULL) {
        ERR("Failed to create buftab\n");
        cleanup(THREAD_FAILURE);
    }

    if ((envp->videoStd == VideoStd_720P_60) && (!envp->passThrough)) {
        cAttrs.videoStd = VideoStd_720P_30;
    }
    else {
        cAttrs.videoStd = envp->videoStd;    
    }
    cAttrs.colorSpace = colorSpace;
    cAttrs.captureDimension = &dim;
    cAttrs.numBufs = NUM_CAPTURE_BUFS;
    hCapture = Capture_create(hBufTab, &cAttrs);

    if (hCapture == NULL) {
        ERR("Failed to create capture device\n");
        cleanup(THREAD_FAILURE);
    }

    /* Get a buffer from the video thread */
    fifoRet = Fifo_get(envp->hInFifo, &hDstBuf);

    if (fifoRet < 0) {
        ERR("Failed to get buffer from video thread\n");
        cleanup(THREAD_FAILURE);
    }

    if (fifoRet == Dmai_EFLUSH) {
        cleanup(THREAD_SUCCESS);
    }

    /* Signal that initialization is done and wait for other threads */
    Rendezvous_meet(envp->hRendezvousInit);

    while (!gblGetQuit()) {
        
        /* Get a buffer from the capture driver to encode */
        if (Capture_get(hCapture, &hCapBuf) < 0) {
            ERR("Failed to get capture buffer\n");
            cleanup(THREAD_FAILURE);
        }

        /* Send captured buffer to video thread for encoding */
        if (Fifo_put(envp->hOutFifo, hCapBuf) < 0) {
            ERR("Failed to send buffer to video thread\n");
            cleanup(THREAD_FAILURE);
        }

        /* Pause processing? */
        Pause_test(envp->hPauseProcess);

        /* Get a buffer from the video thread */
        fifoRet = Fifo_get(envp->hInFifo, &hDstBuf);

        if (fifoRet < 0) {
            ERR("Failed to get buffer from video thread\n");
            cleanup(THREAD_FAILURE);
        }

        /* Did the video thread flush the fifo? */
        if (fifoRet == Dmai_EFLUSH) {
            cleanup(THREAD_SUCCESS);
        }

        /* Return a buffer to the capture driver */
        if (Capture_put(hCapture, hDstBuf) < 0) {
            ERR("Failed to put capture buffer\n");
            cleanup(THREAD_FAILURE);
        }
    }

cleanup:
    /* Make sure the other threads aren't waiting for us */
    Rendezvous_force(envp->hRendezvousCapStd);
    Rendezvous_force(envp->hRendezvousInit);
    Pause_off(envp->hPauseProcess);
    Fifo_flush(envp->hOutFifo);

    /* Meet up with other threads before cleaning up */
    Rendezvous_meet(envp->hRendezvousCleanup);

    if (hCapture) {
        Capture_delete(hCapture);
    }

    /* Clean up the thread before exiting */
    if (hBufTab) {
        BufTab_delete(hBufTab);
    }

    return status;
}
Example #5
0
/******************************************************************************
 * displayThrFxn
 ******************************************************************************/
Void *displayThrFxn(Void *arg)
{
    DisplayEnv             *envp       = (DisplayEnv *) arg;
    Display_Attrs           dAttrs     = Display_Attrs_DM365_VID_DEFAULT;
    Display_Handle          hDisplay   = NULL;
    Framecopy_Handle        hFc        = NULL;
    Void                   *status     = THREAD_SUCCESS;
    Uns                     frameCnt   = 0;
    BufferGfx_Dimensions    srcDim;
    Buffer_Handle           hSrcBuf, hDstBuf;
    Int                     fifoRet;
    ColorSpace_Type         colorSpace = ColorSpace_YUV420PSEMI;
    BufferGfx_Attrs         gfxAttrs = BufferGfx_Attrs_DEFAULT;
    BufTab_Handle           hBufTab  = NULL;
    Int32                   bufSize;
    Time_Attrs              tAttrs   = Time_Attrs_DEFAULT;
    Time_Handle             hTime    = NULL;
    Int32                   time, waitTime;
    Int                     bufCnt = 1;

    hTime = Time_create(&tAttrs);

    if (hTime == NULL) {
        ERR("Failed to create Time object\n");
        cleanup(THREAD_FAILURE);
    }

    if(Time_reset(hTime) != Dmai_EOK) {
        ERR("Failed to reset timer\n");
        cleanup(THREAD_FAILURE);
    }

    /* Signal that initialization is done and wait for other threads */
    Rendezvous_meet(envp->hRendezvousInit);

    while (!gblGetQuit()) {
        /* Pause processing? */
        Pause_test(envp->hPauseProcess);

        /* Pause for priming? */
        Pause_test(envp->hPausePrime);

        /* Get decoded video frame */
        fifoRet = Fifo_get(envp->hInFifo, &hSrcBuf);

        if (fifoRet < 0) {
            ERR("Failed to get buffer from video thread\n");
            cleanup(THREAD_FAILURE);
        }

        /* Did the video thread flush the fifo? */
        if (fifoRet == Dmai_EFLUSH) {
            cleanup(THREAD_SUCCESS);
        }
        
        BufferGfx_getDimensions(hSrcBuf, &srcDim);

        /* Prime the display driver with the first NUM_DISPLAY_BUFS buffers */
        if (bufCnt <= NUM_DISPLAY_BUFS) { 
            if (bufCnt == 1) {  // Create the Display at the first frame
                gfxAttrs.dim.width = srcDim.width;
                gfxAttrs.dim.height = srcDim.height;
                gfxAttrs.dim.lineLength = srcDim.lineLength;
                gfxAttrs.dim.x = srcDim.x;
                gfxAttrs.dim.y = srcDim.y;
                if (colorSpace ==  ColorSpace_YUV420PSEMI) {
                    bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 
                        3 / 2;
                } else {
                    bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 2;
                }

                /* Create a table of buffers to use with the device drivers */
                gfxAttrs.colorSpace = colorSpace;
                hBufTab = BufTab_create(NUM_DISPLAY_BUFS, bufSize,
                    BufferGfx_getBufferAttrs(&gfxAttrs));
                if (hBufTab == NULL) {
                    ERR("Failed to create buftab\n");
                    cleanup(THREAD_FAILURE);
                }
	
                /* Create the display device instance */
                dAttrs.delayStreamon = TRUE;
                dAttrs.numBufs = NUM_DISPLAY_BUFS;
                dAttrs.videoStd = envp->videoStd;
                /* 
                 * Round down the width to a multiple of 32 as required by 
                 * display driver. Otherwise, the driver would internally round
                 * up the width, resulting in the codec padding showing up
                 * on the display when the image width is not a multiple of 32.
                 */
                dAttrs.width = ((gfxAttrs.dim.width & 0x1f) ?
                    (gfxAttrs.dim.width & ~(0x1f)) : gfxAttrs.dim.width);
                dAttrs.height = gfxAttrs.dim.height;
                dAttrs.videoOutput = envp->displayOutput;
                dAttrs.colorSpace  = colorSpace;
                hDisplay = Display_create(hBufTab, &dAttrs);

                if (hDisplay == NULL) {
                    ERR("Failed to create display device\n");
                    cleanup(THREAD_FAILURE);
                }
            }

            bufCnt++;
        }
        else {
            /* Get a buffer from the display device driver */
            if (Display_get(hDisplay, &hDstBuf) < 0) {
                ERR("Failed to get display buffer\n");
                cleanup(THREAD_FAILURE);
            }

            /* Send buffer back to the video thread */
            if (Fifo_put(envp->hOutFifo, hDstBuf) < 0) {
                ERR("Failed to send buffer to video thread\n");
                cleanup(THREAD_FAILURE);
            }
        }

        if (envp->videoStd == VideoStd_720P_60) {
            if (Time_delta(hTime, (UInt32*)&time) < 0) {
                ERR("Failed to get timer delta\n");
                cleanup(THREAD_FAILURE);
            }
            waitTime = DISPLAYLOOPLATENCY - time;
            if(waitTime > 0) {
                usleep(waitTime);
            }
            if(Time_reset(hTime) != Dmai_EOK) {
                ERR("Failed to reset timer\n");
                cleanup(THREAD_FAILURE);
            }
        }

        /* Incremement statistics for the user interface */
        gblIncFrames();           

        /* Give a filled buffer back to the display device driver */
        if (Display_put(hDisplay, hSrcBuf) < 0) {
            ERR("Failed to put display buffer\n");
            cleanup(THREAD_FAILURE);
        }

        frameCnt++;
    }

cleanup:
    /* Make sure the other threads aren't waiting for us */
    Rendezvous_force(envp->hRendezvousInit);
    Pause_off(envp->hPauseProcess);
    Pause_off(envp->hPausePrime);
    Fifo_flush(envp->hOutFifo);

    /* Meet up with other threads before cleaning up */
    Rendezvous_meet(envp->hRendezvousCleanup);

    /* Clean up the thread before exiting */
    if (hFc) {
        Framecopy_delete(hFc);
    }

    if (hDisplay) {
        Display_delete(hDisplay);
    }

    /* Clean up the thread before exiting */
    if (hBufTab) {
        BufTab_delete(hBufTab);
    }

    if(hTime) {
        Time_delete(hTime);
    }

    return status;
}
Example #6
0
File: appMain.c Project: sv99/DVSDK
/******************************************************************************
 * appMain
 ******************************************************************************/
Int appMain(Args * args)
{
    VIDENC1_Params         params    = Venc1_Params_DEFAULT;
    VIDENC1_DynamicParams  dynParams = Venc1_DynamicParams_DEFAULT;
    BufferGfx_Attrs        gfxAttrs  = BufferGfx_Attrs_DEFAULT;
    Buffer_Attrs           bAttrs    = Buffer_Attrs_DEFAULT;
    Time_Attrs             tAttrs    = Time_Attrs_DEFAULT;
    Venc1_Handle           hVe1      = NULL;
    FILE                  *outFile   = NULL;
    FILE                  *reconFile = NULL;
    FILE                  *inFile    = NULL;
    Engine_Handle          hEngine   = NULL;
    Time_Handle            hTime     = NULL;
    Bool                   flushed   = FALSE;
    Bool                   mustExit  = FALSE;
    BufTab_Handle          hBufTab   = NULL;
    Buffer_Handle          hOutBuf   = NULL;
    Buffer_Handle          hFreeBuf  = NULL;
    Buffer_Handle          hInBuf    = NULL;
    Buffer_Handle          hReconBuf = NULL;
    Int                    numFrame  = 0;
    Int                    flushCntr = 1;
    Int                    bufIdx;
    Int                    inBufSize, outBufSize;
    Cpu_Device             device;
    Int                    numBufs;
    ColorSpace_Type        colorSpace;
    UInt32                 time;
    Int                    ret = Dmai_EOK;

    printf("Starting application...\n");

    /* Initialize the codec engine run time */
    CERuntime_init();

    /* Initialize DMAI */
    Dmai_init();

    /* Determine which device the application is running on */
    if (Cpu_getDevice(NULL, &device) < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to determine target board\n");
        goto cleanup;
    }

    if (args->benchmark) {
        hTime = Time_create(&tAttrs);

        if (hTime == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create Time object\n");
            goto cleanup;
        }
    }

    /* Open the input file with raw yuv data */
    inFile = fopen(args->inFile, "rb");

    if (inFile == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open input file %s\n", args->inFile);
        goto cleanup;
    }

    /* Using a larger vbuf to enhance performance of file i/o */
    if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to setvbuf on input file descriptor\n");
        goto cleanup;
    }

    /* Open the output file where to put encoded data */
    outFile = fopen(args->outFile, "wb");

    if (outFile == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open output file %s\n", args->outFile);
        goto cleanup;
    }

    /* Using a larger vbuf to enhance performance of file i/o */
    if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to setvbuf on output file descriptor\n");
        goto cleanup;
    }

    /* Open the output file where to put reconstructed frames */
    if (args->writeReconFrames) {
        reconFile = fopen(args->reconFile, "wb");

        if (reconFile == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to open output file %s\n", args->reconFile);
            goto cleanup;
        }

        /* Using a larger vbuf to enhance performance of file i/o */
        if (setvbuf(reconFile, vbufferRecon, _IOFBF,
                    sizeof(vbufferRecon)) != 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to setvbuf on output file descriptor\n");
            goto cleanup;
        }
    }

    /* Open the codec engine */
    hEngine = Engine_open(args->engineName, NULL, NULL);

    if (hEngine == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open codec engine: %s\n", args->engineName);
        goto cleanup;
    }

    /* Set up codec parameters depending on bit rate */
    if (args->bitRate < 0) {
        /* Variable bit rate */
        params.rateControlPreset = IVIDEO_NONE;

        /*
         * If variable bit rate use a bogus bit rate value (> 0)
         * since it will be ignored.
         */
        params.maxBitRate        = 2000000;
    }
    else {
        /* Constant bit rate */
        params.rateControlPreset = IVIDEO_LOW_DELAY;
        params.maxBitRate        = args->bitRate;
    }

    /* Set up codec parameters depending on device */
    switch (device) {
    case Cpu_Device_DM6467:
        params.inputChromaFormat = XDM_YUV_420SP;
        params.reconChromaFormat = XDM_CHROMA_NA;
        break;
    case Cpu_Device_DM355:
        params.inputChromaFormat = XDM_YUV_422ILE;
        params.reconChromaFormat = XDM_YUV_420P;
        break;
    case Cpu_Device_DM365:
    case Cpu_Device_DM368:
        params.inputChromaFormat = XDM_YUV_420SP;
        params.reconChromaFormat = XDM_YUV_420SP;
        break;
    case Cpu_Device_DM3730:
        params.rateControlPreset = IVIDEO_STORAGE;
        params.inputChromaFormat = XDM_YUV_422ILE;
        break;
    default:
        params.inputChromaFormat = XDM_YUV_422ILE;
        break;
    }

    params.maxWidth              = args->width;
    params.maxHeight             = args->height;

    /* Workaround for SDOCM00068944: h264fhdvenc fails
       to create codec when params.dataEndianness is
       set as XDM_BYTE */
    if(device == Cpu_Device_DM6467) {
        if (!strcmp(args->codecName, "h264fhdvenc")) {
            params.dataEndianness        = XDM_LE_32;
        }
    }

    params.maxInterFrameInterval = 1;
    dynParams.targetBitRate      = params.maxBitRate;
    dynParams.inputWidth         = params.maxWidth;
    dynParams.inputHeight        = params.maxHeight;

    /* Create the video encoder */
    hVe1 = Venc1_create(hEngine, args->codecName, &params, &dynParams);

    if (hVe1 == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create video encoder: %s\n", args->codecName);
        goto cleanup;
    }

    /* Ask the codec how much input data it needs */
    inBufSize = Venc1_getInBufSize(hVe1);

    /* Ask the codec how much space it needs for output data */
    outBufSize = Venc1_getOutBufSize(hVe1);

    /* Which color space to use in the graphics buffers depends on the device */
    colorSpace = ((device == Cpu_Device_DM6467)||
                  (device == Cpu_Device_DM365) ||
                  (device == Cpu_Device_DM368)) ? ColorSpace_YUV420PSEMI :
                 ColorSpace_UYVY;

    /* Align buffers to cache line boundary */
    gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN;

    /* Use cached buffers if requested */
    if (args->cache) {
        gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags
                                          = Memory_CACHED;
    }

    gfxAttrs.dim.width      = args->width;
    gfxAttrs.dim.height     = args->height;
    if ((device == Cpu_Device_DM6467) || (device == Cpu_Device_DM365)
            || (device == Cpu_Device_DM368)) {
        gfxAttrs.dim.height = Dmai_roundUp(gfxAttrs.dim.height, CODECHEIGHTALIGN);
    }
    gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace);
    gfxAttrs.colorSpace     = colorSpace;

    if (inBufSize < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to calculate buffer attributes\n");
        goto cleanup;
    }

    /* Number of input buffers required */
    if(params.maxInterFrameInterval>1) {
        /* B frame support */
        numBufs = params.maxInterFrameInterval;
    }
    else {
        numBufs = 1;
    }

    /* Create a table of input buffers of the size requested by the codec */
    hBufTab =
        BufTab_create(numBufs, Dmai_roundUp(inBufSize, BUFSIZEALIGN),
                      BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hBufTab == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to allocate contiguous buffers\n");
        goto cleanup;
    }

    /* Set input buffer table */
    Venc1_setBufTab(hVe1, hBufTab);

    /* Create the reconstructed frame buffer for raw yuv data */
    if (args->writeReconFrames) {
        hReconBuf =
            Buffer_create(Dmai_roundUp(inBufSize, BUFSIZEALIGN),
                          BufferGfx_getBufferAttrs(&gfxAttrs));

        if (hReconBuf == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to allocate contiguous buffer\n");
            goto cleanup;
        }
    }

    /* Create the output buffer for encoded video data */
    hOutBuf = Buffer_create(Dmai_roundUp(outBufSize, BUFSIZEALIGN), &bAttrs);

    if (hOutBuf == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create contiguous buffer\n");
        goto cleanup;
    }

    while (1) {

        /* Get a buffer for input */
        hInBuf = BufTab_getFreeBuf(hBufTab);

        if (hInBuf == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get a free contiguous buffer from BufTab\n");
            BufTab_print(hBufTab);
            goto cleanup;
        }

        if (args->benchmark) {
            if (Time_reset(hTime) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to reset timer\n");
                goto cleanup;
            }
        }

        /* Read a yuv input frame */
        printf("\n Frame %d: ", numFrame);
        if ((device == Cpu_Device_DM6467)||
                (device == Cpu_Device_DM365) ||
                (device == Cpu_Device_DM368)) {
            if(args->sp) {
                if (readFrame420SP(hInBuf, inFile, args->height) < 0) {
                    ret = Dmai_EFAIL;
                    goto cleanup;
                }
            } else {
                if (readFrame420P(hInBuf, inFile, args->height) < 0) {
                    ret = Dmai_EFAIL;
                    goto cleanup;
                }
            }
        }
        else {
            if (readFrameUYVY(hInBuf, inFile) < 0) {
                ret = Dmai_EFAIL;
                mustExit = TRUE;
            }
        }

        if (++numFrame == args->numFrames||mustExit == TRUE) {
            if(!(params.maxInterFrameInterval>1)) {
                /* No B-frame support */
                printf("... exiting \n");
                goto cleanup;
            }

            /*
             * When encoding a stream with B-frames, ending the processing
             * requires to free the buffer held by the encoder. This is done by
             * flushing the encoder and performing a last process() call
             * with a dummy input buffer.
             */
            printf("\n... exiting with flush (B-frame stream) \n");
            flushCntr = params.maxInterFrameInterval-1;
            flushed = TRUE;
            Venc1_flush(hVe1);
        }

        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer delta\n");
                goto cleanup;
            }

            printf("Read time: %uus\n", (Uns)time);
        }

        /*
         * Following flushing loop will iterate more than one time only
         * when the encoder completes processing by flushing the frames
         * held by the encoder. All flushed frames will be encoded as P
         * or I frames.
         */

        for(bufIdx = 0; bufIdx < flushCntr; bufIdx++) {

            if (args->cache) {
                /*
                *  To meet xDAIS DMA Rule 7, when input buffers are cached, we
                *  must writeback the cache into physical memory.  Also, per DMA
                *  Rule 7, we must invalidate the output buffer from
                *  cache before providing it to any xDAIS algorithm.
                */
                Memory_cacheWbInv(Buffer_getUserPtr(hInBuf),
                                  Buffer_getSize(hInBuf));

                /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
                Memory_cacheInv(Buffer_getUserPtr(hOutBuf),
                                Buffer_getSize(hOutBuf));

                if (args->benchmark) {
                    if (Time_delta(hTime, &time) < 0) {
                        ret = Dmai_EFAIL;
                        fprintf(stderr,"Failed to get timer delta\n");
                        goto cleanup;
                    }

                    printf("Pre-process cache maintenance: %uus \n", (Uns) time);
                }
            }

            /* Make sure the whole buffer is used for input */
            BufferGfx_resetDimensions(hInBuf);

            /* Encode the video buffer */
            if (Venc1_process(hVe1, hInBuf, hOutBuf) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to encode video buffer\n");
                goto cleanup;
            }

            /* if encoder generated output content, free released buffer */
            if (Buffer_getNumBytesUsed(hOutBuf)>0) {
                /* Get free buffer */
                hFreeBuf = Venc1_getFreeBuf(hVe1);
                /* Free buffer */
                BufTab_freeBuf(hFreeBuf);
            }
            /* if encoder did not generate output content */
            else {
                /* if non B frame sequence */
                /* encoder skipped frame probably exceeding target bitrate */
                if (params.maxInterFrameInterval<=1) {
                    /* free buffer */
                    printf(" Encoder generated 0 size frame\n");
                    BufTab_freeBuf(hInBuf);
                }
            }

            if (args->benchmark) {
                if (Time_delta(hTime, &time) < 0) {
                    ret = Dmai_EFAIL;
                    fprintf(stderr,"Failed to get encode time\n");
                    goto cleanup;
                }

                printf("[%d] Encode: %uus\n", numFrame, (Uns)time);
            }

            if (args->cache) {
                /* Writeback the outBuf. */
                Memory_cacheWb(Buffer_getUserPtr(hOutBuf),
                               Buffer_getSize(hOutBuf));

                if (args->benchmark) {
                    if (Time_delta(hTime, &time) < 0) {
                        ret = Dmai_EFAIL;
                        fprintf(stderr,"Failed to get timer delta\n");
                        goto cleanup;
                    }

                    printf("Post-process cache write back: %uus \n", (Uns) time);
                }
            }

            /* Write the encoded frame to the file system */
            if (Buffer_getNumBytesUsed(hOutBuf)) {
                if (fwrite(Buffer_getUserPtr(hOutBuf),
                           Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) {
                    ret = Dmai_EFAIL;
                    fprintf(stderr,"Failed to write encoded video data to file\n");
                    goto cleanup;
                }
            }

            /* Write the reconstructed frame to the file system */
            if (args->writeReconFrames) {
                processReconData(Venc1_getReconBufs(hVe1), hInBuf, hReconBuf);

                if (Buffer_getNumBytesUsed(hReconBuf)) {
                    if (fwrite(Buffer_getUserPtr(hReconBuf),
                               Buffer_getNumBytesUsed(hReconBuf), 1, reconFile) != 1) {
                        ret = Dmai_EFAIL;
                        fprintf(stderr,"Failed to write reconstructed frame to file\n");
                        goto cleanup;
                    }
                }
            }

            if (args->benchmark) {
                if (Time_delta(hTime, &time) < 0) {
                    ret = Dmai_EFAIL;
                    printf("Failed to get timer delta\n");
                    goto cleanup;
                }

                printf("File write time: %uus\n", (Uns)time);

                if (Time_total(hTime, &time) < 0) {
                    ret = Dmai_EFAIL;
                    fprintf(stderr,"Failed to get timer total\n");
                    goto cleanup;
                }

                printf("Total: %uus\n", (Uns)time);
            }
        }

        /* If the codec flushing completed, exit main thread */
        if (flushed) {
            /* Free dummy input buffer used for flushing process() calls */
            printf("freeing dummy input buffer ... \n");
            BufTab_freeBuf(hInBuf);
            break;
        }
    }

cleanup:
    /* Clean up the application */
    if (hOutBuf) {
        Buffer_delete(hOutBuf);
    }

    if (hReconBuf) {
        Buffer_delete(hReconBuf);
    }

    if (hVe1) {
        Venc1_delete(hVe1);
    }

    if (hBufTab) {
        BufTab_delete(hBufTab);
    }

    if (hEngine) {
        Engine_close(hEngine);
    }

    if (inFile) {
        fclose(inFile);
    }

    if (outFile) {
        fclose(outFile);
    }

    if (reconFile) {
        fclose(reconFile);
    }

    if (hTime) {
        Time_delete(hTime);
    }

    printf("End of application.\n");

    if (ret == Dmai_EFAIL)
        return 1;
    else
        return 0;
}
Example #7
0
/******************************************************************************
 * captureThrFxn
 ******************************************************************************/
Void *captureThrFxn(Void *arg)
{
    CaptureEnv           *envp     = (CaptureEnv *) arg;
    Void                 *status   = THREAD_SUCCESS;
    Capture_Attrs         cAttrs   = Capture_Attrs_DM365_DEFAULT;
    Display_Attrs         dAttrs   = Display_Attrs_DM365_VID_DEFAULT;
    BufferGfx_Attrs       gfxAttrs = BufferGfx_Attrs_DEFAULT;    
    Capture_Handle        hCapture = NULL;
    Display_Handle        hDisplay = NULL;
    BufTab_Handle         hBufTab  = NULL;
    BufTab_Handle         hDispBufTab = NULL;
    BufTab_Handle         hFifoBufTab = NULL;
    Buffer_Handle         hDstBuf, hCapBuf, hDisBuf, hBuf;
    BufferGfx_Dimensions  capDim;
    VideoStd_Type         videoStd;
    Int32                 width, height, bufSize;
    Int                   fifoRet;
    ColorSpace_Type       colorSpace = ColorSpace_YUV420PSEMI;
    Int                   bufIdx;
    Int                   numCapBufs;

    /* Create capture device driver instance */
    cAttrs.numBufs = NUM_CAPTURE_BUFS;
    cAttrs.videoInput = envp->videoInput;
    cAttrs.videoStd = envp->videoStd;
    cAttrs.colorSpace = colorSpace;

    videoStd = envp->videoStd;

    /* We only support D1, 720P and 1080P input */
    if (videoStd != VideoStd_D1_NTSC && videoStd != VideoStd_D1_PAL 
        && videoStd != VideoStd_720P_60 && videoStd != VideoStd_720P_50 &&
        videoStd != VideoStd_1080I_30) {
        ERR("Need D1/720P/1080P input to this demo\n");
        cleanup(THREAD_FAILURE);
    }
    if (envp->imageWidth > 0 && envp->imageHeight > 0) {
        if (VideoStd_getResolution(videoStd, &width, &height) < 0) {
            ERR("Failed to calculate resolution of video standard\n");
            cleanup(THREAD_FAILURE);
        }

        if (width < envp->imageWidth && height < envp->imageHeight) {
            ERR("User resolution (%ldx%ld) larger than detected (%ldx%ld)\n",
                envp->imageWidth, envp->imageHeight, width, height);
            cleanup(THREAD_FAILURE);
        }

       /*
        * Capture driver provides 32 byte aligned data. We 32 byte align the
        * capture and video buffers to perform zero copy encoding.
        */
        envp->imageWidth  = Dmai_roundUp(envp->imageWidth,32);
        capDim.x          = 0;
        capDim.y          = 0;
        capDim.height     = envp->imageHeight;
        capDim.width      = envp->imageWidth;
        capDim.lineLength = BufferGfx_calcLineLength(capDim.width, colorSpace);
    } 
    else {
        /* Calculate the dimensions of a video standard given a color space */
        if (BufferGfx_calcDimensions(videoStd, colorSpace, &capDim) < 0) {
            ERR("Failed to calculate Buffer dimensions\n");
            cleanup(THREAD_FAILURE);
        }

       /*
        * Capture driver provides 32 byte aligned data. We 32 byte align the
        * capture and video buffers to perform zero copy encoding.
        */
        capDim.width      = Dmai_roundUp(capDim.width,32);
        envp->imageWidth  = capDim.width;
        envp->imageHeight = capDim.height;
    }

    numCapBufs = NUM_CAPTURE_BUFS;

    gfxAttrs.dim.height = capDim.height;
    gfxAttrs.dim.width = capDim.width;
    gfxAttrs.dim.lineLength = 
        Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width,
                     colorSpace), 32);
    gfxAttrs.dim.x = 0;
    gfxAttrs.dim.y = 0;
    if (colorSpace ==  ColorSpace_YUV420PSEMI) {
        bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 3 / 2;
    } 
    else {
        bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 2;
    }

    /* Create a table of buffers to use with the capture driver */
    gfxAttrs.colorSpace = colorSpace;
    hBufTab = BufTab_create(numCapBufs, bufSize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));
    if (hBufTab == NULL) {
        ERR("Failed to create buftab\n");
        cleanup(THREAD_FAILURE);
    }

    /* Create a table of buffers to use to prime Fifo to video thread */
    hFifoBufTab = BufTab_create(VIDEO_PIPE_SIZE, bufSize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));
    if (hFifoBufTab == NULL) {
        ERR("Failed to create buftab\n");
        cleanup(THREAD_FAILURE);
    }

    /* Update global data for user interface */
    gblSetImageWidth(envp->imageWidth);
    gblSetImageHeight(envp->imageHeight);

    /* Report the video standard and image size back to the main thread */
    Rendezvous_meet(envp->hRendezvousCapStd);

    /* Capture at half frame rate if using COMPONENT input at 720P */
    if ((envp->videoStd == VideoStd_720P_60) 
        && (envp->videoInput == Capture_Input_COMPONENT)) {
        cAttrs.videoStd = VideoStd_720P_30;
    }
    else {
        cAttrs.videoStd = envp->videoStd;    
    }

    /*If its component input and video std is 1080I_30 then make it 1080I_60.*/
    if (cAttrs.videoStd == VideoStd_1080I_30 && cAttrs.videoInput 
                        == Capture_Input_COMPONENT) {
        cAttrs.videoStd = VideoStd_1080I_60;
    }

    cAttrs.numBufs    = NUM_CAPTURE_BUFS;    
    cAttrs.colorSpace = colorSpace;
    cAttrs.captureDimension = &gfxAttrs.dim;
    /* Create the capture device driver instance */
    hCapture = Capture_create(hBufTab, &cAttrs);

    if (hCapture == NULL) {
        ERR("Failed to create capture device. Is video input connected?\n");
        cleanup(THREAD_FAILURE);
    }

    /* Create a table of buffers to use with the display driver */
    hDispBufTab = BufTab_create(NUM_DISPLAY_BUFS, bufSize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));
    if (hDispBufTab == NULL) {
        ERR("Failed to create buftab\n");
        cleanup(THREAD_FAILURE);
    }

    /* Create display device driver instance if preview is needed */
    if (!envp->previewDisabled) {
        dAttrs.videoStd = envp->videoStd;
        if ( (dAttrs.videoStd == VideoStd_CIF) ||
            (dAttrs.videoStd == VideoStd_SIF_NTSC) ||
            (dAttrs.videoStd == VideoStd_SIF_PAL) ||
            (dAttrs.videoStd == VideoStd_VGA) ||
            (dAttrs.videoStd == VideoStd_D1_NTSC) ||        
            (dAttrs.videoStd == VideoStd_D1_PAL) ) {
            dAttrs.videoOutput = Display_Output_COMPOSITE;
        } else {
            dAttrs.videoOutput = Display_Output_COMPONENT;
        }    
        dAttrs.numBufs    = NUM_DISPLAY_BUFS;
        dAttrs.colorSpace = colorSpace;
        dAttrs.width = capDim.width;
        dAttrs.height = capDim.height;
        hDisplay = Display_create(hDispBufTab, &dAttrs);

        if (hDisplay == NULL) {
            ERR("Failed to create display device\n");
            cleanup(THREAD_FAILURE);
        }
    }

    for (bufIdx = 0; bufIdx < VIDEO_PIPE_SIZE; bufIdx++) {
        /* Queue the video buffers for main thread processing */
        hBuf = BufTab_getFreeBuf(hFifoBufTab);
        if (hBuf == NULL) {
            ERR("Failed to fill video pipeline\n");
            cleanup(THREAD_FAILURE);            
        }

       /* Fill with black the buffer */
       CapBuf_blackFill(hBuf);

        /* Send buffer to video thread for encoding */
        if (Fifo_put(envp->hOutFifo, hBuf) < 0) {
            ERR("Failed to send buffer to display thread\n");
            cleanup(THREAD_FAILURE);
        }
    }
    /* Signal that initialization is done and wait for other threads */
    Rendezvous_meet(envp->hRendezvousInit);

    while (!gblGetQuit()) {
        /* Pause processing? */
        Pause_test(envp->hPauseProcess);

        /* Capture a frame */
        if (Capture_get(hCapture, &hCapBuf) < 0) {
            ERR("Failed to get capture buffer\n");
            cleanup(THREAD_FAILURE);
        }

        /* Get a buffer from the display device */
        if ((!envp->previewDisabled) && (Display_get(hDisplay, &hDisBuf) < 0)) {
            ERR("Failed to get display buffer\n");
            cleanup(THREAD_FAILURE);
        }
        /* Send buffer to video thread for encoding */
        if (Fifo_put(envp->hOutFifo, hCapBuf) < 0) {
            ERR("Failed to send buffer to display thread\n");
            cleanup(THREAD_FAILURE);
        }

        /* Get a buffer from the video thread */
        fifoRet = Fifo_get(envp->hInFifo, &hDstBuf);

        if (fifoRet < 0) {
            ERR("Failed to get buffer from video thread\n");
            cleanup(THREAD_FAILURE);
        }

        /* Did the video thread flush the fifo? */
        if (fifoRet == Dmai_EFLUSH) {
            cleanup(THREAD_SUCCESS);
        }

        if (!envp->previewDisabled) {
            /* Release buffer to the display device driver */
            if (Display_put(hDisplay, hDstBuf) < 0) {
                ERR("Failed to put display buffer\n");
                cleanup(THREAD_FAILURE);
            }
        }

        if (envp->previewDisabled) {
            /* Return the processed buffer to the capture driver */
            if (Capture_put(hCapture, hDstBuf) < 0) {
                ERR("Failed to put capture buffer\n");
                cleanup(THREAD_FAILURE);
            } 
        }
        else {
            /* Return the displayed buffer to the capture driver */
            if (Capture_put(hCapture, hDisBuf) < 0) {
                ERR("Failed to put capture buffer\n");
                cleanup(THREAD_FAILURE);
            }
        }

        /* Increment statistics for the user interface */
        gblIncFrames();

    }

cleanup:
    /* Make sure the other threads aren't waiting for us */
    Rendezvous_force(envp->hRendezvousCapStd);
    Rendezvous_force(envp->hRendezvousInit);
    Pause_off(envp->hPauseProcess);
    Fifo_flush(envp->hOutFifo);

    /* Meet up with other threads before cleaning up */
    Rendezvous_meet(envp->hRendezvousCleanup);

    if (hDisplay) {
        Display_delete(hDisplay);
    }

    if (hCapture) {
        Capture_delete(hCapture);
    }
    
    /* Clean up the thread before exiting */
    if (hBufTab) {
        BufTab_delete(hBufTab);
    }
    if (hFifoBufTab) {
        BufTab_delete(hFifoBufTab);
    }
    if (hDispBufTab) {
        BufTab_delete(hDispBufTab);
    }

    return status;
}
/******************************************************************************
 * Display_fbdev_create
 ******************************************************************************/
Display_Handle Display_fbdev_create(BufTab_Handle hBufTab, Display_Attrs *attrs)
{
    BufferGfx_Attrs         gfxAttrs       = BufferGfx_Attrs_DEFAULT;
    struct fb_var_screeninfo varInfo;
    struct fb_fix_screeninfo fixInfo;
    Int                      displaySize;
    Int                      bufIdx;
    Int8                    *virtPtr;
    Int32                    physPtr;
    Int32                    height, width;
    Display_Handle           hDisplay;
    Buffer_Handle            hBuf;

    if (attrs == NULL) {
        Dmai_err0("Must supply valid attrs\n");
        return NULL;
    }

    if (hBufTab != NULL) {
        Dmai_err0("FBdev display does not accept user allocated buffers\n");
        return NULL;
    }

    hDisplay = calloc(1, sizeof(Display_Object));

    if (hDisplay == NULL) {
        Dmai_err0("Failed to allocate space for Display Object\n");
        return NULL;
    }

    /* Open video display device */
    hDisplay->fd = open(attrs->displayDevice, O_RDWR);

    if (hDisplay->fd == -1) {
        Dmai_err2("Failed to open fb device %s (%s)\n", attrs->displayDevice,
                                                        strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    /* Get fixed screen info */
    if (ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo) == -1) {
        Dmai_err2("Failed FBIOGET_FSCREENINFO on %s (%s)\n",
                  attrs->displayDevice, strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    /* Get virtual screen info */
    if (ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo) == -1) {
        Dmai_err2("Failed FBIOGET_VSCREENINFO on %s (%s)\n",
                  attrs->displayDevice, strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    Dmai_dbg5("Found width=%d height=%d, yres_virtual=%d,xres_virtual=%d,"
              " line_length=%d\n", varInfo.xres, varInfo.yres, 
                varInfo.yres_virtual,varInfo.xres_virtual, fixInfo.line_length);

    /* Save current virtual screen info. */
    memcpy(&hDisplay->origVarInfo, &varInfo, sizeof(struct fb_var_screeninfo));

    /* If video standard is set to auto then use current height and width */
    if (attrs->videoStd == VideoStd_AUTO) {
        width = varInfo.xres;
        height = varInfo.yres;
    }
    /* If video standard is not set then use the height/width passed from 
     * attribute.
     */
    else if (attrs->videoStd == -1) {
        width = attrs->width;
        height = attrs->height; 
    }
    /* calulcate height/width from video standard */
    else {
        VideoStd_getResolution(attrs->videoStd, &width, &height);
    }

    if (attrs->width > 0) {
        width = attrs->width;
    }

    if (attrs->height > 0) {
        height = attrs->height;
    }

    if (width > varInfo.xres) { 
        width = varInfo.xres;
    }

    if (height > varInfo.yres) {
        height = varInfo.yres;
    }

    varInfo.xoffset         = 0;
    varInfo.yoffset         = 0;
    varInfo.xres            = width;
    varInfo.yres            = height;
    varInfo.xres_virtual    = width;
    varInfo.yres_virtual    = varInfo.yres * attrs->numBufs;

    /* Set video display format */
    Dmai_dbg4("Setting width=%d height=%d, yres_virtual=%d,"
              " xres_virtual=%d\n", varInfo.xres, varInfo.yres, 
              varInfo.yres_virtual, varInfo.xres_virtual);

    if (ioctl(hDisplay->fd, FBIOPUT_VSCREENINFO, &varInfo) == -1) {
        Dmai_err2("Failed FBIOPUT_VSCREENINFO on %s (%s)\n",
                  attrs->displayDevice, strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    if (ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo) == -1) {
        Dmai_err2("Failed FBIOGET_FSCREENINFO on %s (%s)\n",
                  attrs->displayDevice, strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    Dmai_dbg5("New width=%d, height=%d, yres_virtual=%d,xres_virtual=%d, "
              "line_length=%d\n", varInfo.xres, varInfo.yres, 
              varInfo.yres_virtual, varInfo.xres_virtual, fixInfo.line_length);

    gfxAttrs.dim.width          = varInfo.xres;
    gfxAttrs.colorSpace         = attrs->colorSpace;
    gfxAttrs.dim.height         = varInfo.yres;
    gfxAttrs.dim.lineLength     = fixInfo.line_length;
    gfxAttrs.bAttrs.reference   = TRUE;
    displaySize                 = fixInfo.line_length * varInfo.yres;

    hBufTab = BufTab_create(attrs->numBufs, displaySize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hBufTab == NULL) {
        Dmai_err0("Failed to allocate BufTab for display buffers\n");
        cleanup(hDisplay);
        return NULL;
    }

    hBuf = BufTab_getBuf(hBufTab, 0);

    Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
                                 varInfo.bits_per_pixel / 8);
    virtPtr = (Int8 *) mmap (NULL,
                             displaySize * attrs->numBufs,
                             PROT_READ | PROT_WRITE,
                             MAP_SHARED,
                             hDisplay->fd, 0);

    if (virtPtr == MAP_FAILED) {
        Dmai_err2("Failed mmap on %s (%s)\n", attrs->displayDevice,
                                              strerror(errno));
        cleanup(hDisplay);
        return NULL;
    }

    if (Buffer_setUserPtr(hBuf, virtPtr) < 0) {
        cleanup(hDisplay);
        return NULL;
    }

    _Dmai_blackFill(hBuf);

    Dmai_dbg3("Display buffer %d mapped to %#lx has physical address %#lx\n", 0,
              (Int32) virtPtr, physPtr);

    for (bufIdx=1; bufIdx < attrs->numBufs; bufIdx++) {
        hBuf = BufTab_getBuf(hBufTab, bufIdx);
        Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
                                     varInfo.bits_per_pixel / 8);

        virtPtr = virtPtr + displaySize;
        Buffer_setUserPtr(hBuf, virtPtr);
        _Dmai_blackFill(hBuf);

        Dmai_dbg3("Display buffer %d mapped to %#lx, physical address %#lx\n",
                  bufIdx, (unsigned long) virtPtr, physPtr);
    }

    hDisplay->hBufTab = hBufTab;
    hDisplay->displayIdx = 0;
    hDisplay->workingIdx = attrs->numBufs > 1 ? 1 : 0;
    hDisplay->displayStd = Display_Std_FBDEV;

    if (setDisplayBuffer(hDisplay, hDisplay->displayIdx) < 0) {
        cleanup(hDisplay);
        return NULL;
    }

    return hDisplay;
}
Example #9
0
/******************************************************************************
 * appMain
 ******************************************************************************/
Void appMain(Args * args)
{
    VIDENC_Params           params      = Venc_Params_DEFAULT;
    VIDENC_DynamicParams    dynParams   = Venc_DynamicParams_DEFAULT;
    BufferGfx_Attrs         gfxAttrs    = BufferGfx_Attrs_DEFAULT;
    Buffer_Attrs            bAttrs      = Buffer_Attrs_DEFAULT;
    Time_Attrs              tAttrs      = Time_Attrs_DEFAULT;
    Venc_Handle             hVe         = NULL;
    FILE                   *outFile     = NULL;
    FILE                   *inFile      = NULL;
    Engine_Handle           hEngine     = NULL;
    Time_Handle             hTime       = NULL;
    Int                     numFrame    = 0;
    Buffer_Handle           hOutBuf     = NULL;
    Buffer_Handle           hInBuf      = NULL;
    ColorSpace_Type         colorSpace;
    UInt32                  time;

    printf("Starting application...\n");
    
    /* Initialize the codec engine run time */
    CERuntime_init();
    
    /* Initialize DMAI */
    Dmai_init();
    
    if (args->benchmark) {
        hTime = Time_create(&tAttrs);

        if (hTime == NULL) {
            printf("Failed to create Time object\n");
            goto cleanup;
        }
    }

    /* Open input file */
    inFile = fopen(args->inFile, "rb");
    
    if (inFile == NULL) {
        printf("Failed to open input file %s\n", args->inFile);
        goto cleanup;
    }

    /* Using a larger vbuf to enhance performance of file i/o */
    if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) {
        printf("Failed to setvbuf on input file descriptor\n");
        goto cleanup;   
    }   

    
    /* Open output file */
    outFile = fopen(args->outFile, "wb");

    if (outFile == NULL) {
        printf("Failed to open output file %s\n", args->outFile);
        goto cleanup;
    }

    /* Using a larger vbuf to enhance performance of file i/o */
    if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) {
        printf("Failed to setvbuf on output file descriptor\n");
        goto cleanup;   
    }
    
    /* Open the codec engine */
    hEngine = Engine_open(args->engineName, NULL, NULL);

    if (hEngine == NULL) {
        printf("Failed to open codec engine: %s\n", args->engineName);
        goto cleanup;
    }

    params.maxWidth = args->width;
    params.maxHeight = args->height;

    /* Set up codec parameters depending on bit rate */
    if (args->bitRate < 0) {
        /* Variable bit rate */
        params.rateControlPreset = IVIDEO_NONE;

        /*
         * If variable bit rate use a bogus bit rate value (> 0)
         * since it will be ignored.
         */
        params.maxBitRate        = 2000000;
    }
    else {
        /* Constant bit rate */
        params.rateControlPreset = IVIDEO_LOW_DELAY;
        params.maxBitRate        = args->bitRate;
    }

    params.inputChromaFormat = XDM_YUV_422ILE;

    dynParams.targetBitRate = params.maxBitRate;
    dynParams.inputWidth = params.maxWidth;
    dynParams.inputHeight = params.maxHeight;
    
    /* Create the video encoder */
    hVe = Venc_create(hEngine, args->codecName, &params, &dynParams);

    if (hVe == NULL) {
        printf("Failed to create video encoder: %s\n", args->codecName);
        goto cleanup;
    }

    /* Only the UYVY colorspace is supported in this application */
    colorSpace = ColorSpace_UYVY;

    /* Align buffers to cache line boundary */    
    gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; 
    
    /* Use cached buffers if requested */    
    if (args->cache) {
        gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags 
            = Memory_CACHED;
    } 
    
    /* Calculate the buffer attributes */
    gfxAttrs.dim.width = args->width;
    gfxAttrs.dim.height = args->height;
    gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace);
    gfxAttrs.colorSpace = colorSpace;

    /* Create input buffer */
    hInBuf = Buffer_create(Dmai_roundUp(Venc_getInBufSize(hVe), BUFSIZEALIGN),
                           BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hInBuf == NULL) {
        printf("Failed to allocate contiguous buffer\n");
        goto cleanup;
    }

    /* Create output buffer */
    hOutBuf = Buffer_create(Dmai_roundUp(Venc_getOutBufSize(hVe), BUFSIZEALIGN),
        &bAttrs);

    if (hOutBuf == NULL) {
        printf("Failed to create contiguous buffer\n");
        goto cleanup;
    }

    while (numFrame++ < args->numFrames) {
        /* Read a yuv input frame */
        printf("Frame %d: ", numFrame);
        if (readFrameUYVY(hInBuf, inFile) < 0) {
            goto cleanup;        
        }
        
        if (args->benchmark) {
            if (Time_reset(hTime) < 0) {
                printf("Failed to reset timer\n");
                goto cleanup;
            }
        }

        if (args->cache) {
            /*  
             *  To meet xDAIS DMA Rule 7, when input buffers are cached, we 
             *  must writeback the cache into physical memory.  Also, per DMA 
             *  Rule 7, we must invalidate the output buffer from
             *  cache before providing it to any xDAIS algorithm.
             */
            Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf));
    
            /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
            Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf));
    
            if (args->benchmark) {
                if (Time_delta(hTime, &time) < 0) {
                    printf("Failed to get timer delta\n");
                    goto cleanup;
                }
    
                printf("Pre-process cache maintenance: %uus \n", (Uns) time);
            }
        }

        /* Encode the video buffer */
        if (Venc_process(hVe, hInBuf, hOutBuf) < 0) {
            printf("Failed to encode video buffer\n");
            goto cleanup;
        }

        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                printf("Failed to get encode time\n");
                goto cleanup;
            }

            printf("[%d] Encode: %uus\n", numFrame, (Uns)time);
        }

        if (args->cache) {
            /* Writeback the outBuf. */
            Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf));
    
            if (args->benchmark) {
                if (Time_delta(hTime, &time) < 0) {
                    printf("Failed to get timer delta\n");
                    goto cleanup;
                }
    
                printf("Post-process cache write back: %uus \n", (Uns) time);
            }
        }
        
        /* Write the encoded frame to the file system */
        if (Buffer_getNumBytesUsed(hOutBuf)) {
            if (fwrite(Buffer_getUserPtr(hOutBuf),
                       Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) {
                printf("Failed to write encoded video data to file\n");
                goto cleanup;
            }
        }
        
        if (args->benchmark) {
            if (Time_total(hTime, &time) < 0) {
                printf("Failed to get timer total\n");
                goto cleanup;
            }

            printf("Total: %uus\n", (unsigned int)time);
        }
    }

cleanup:
    /* Clean up the application */
    if (hOutBuf) {
        Buffer_delete(hOutBuf);
    }

    if (hInBuf) {
        Buffer_delete(hInBuf);
    }

    if (hVe) {
        Venc_delete(hVe);
    }

    if (hEngine) {
        Engine_close(hEngine);
    }

    if (inFile) {
        fclose(inFile);
    }
   
    if (outFile) {
        fclose(outFile);
    }

    if (hTime) {
        Time_delete(hTime);
    }

    printf("End of application.\n");
    
    return;
}
Example #10
0
/******************************************************************************
 * _Dmai_v4l2DriverAlloc
 ******************************************************************************/
Int _Dmai_v4l2DriverAlloc(Int fd, Int numBufs, enum v4l2_buf_type type,
                          struct _VideoBufDesc **bufDescsPtr,
                          BufTab_Handle *hBufTabPtr, Int topOffset, 
                          ColorSpace_Type colorSpace)
{
    BufferGfx_Attrs             gfxAttrs = BufferGfx_Attrs_DEFAULT;
    struct v4l2_requestbuffers  req;
    struct v4l2_format          fmt;
    _VideoBufDesc              *bufDesc;
    Buffer_Handle               hBuf;
    Int                         bufIdx;
    Int8                       *virtPtr;

    Dmai_clear(fmt);
    fmt.type = type;

    if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) {
        Dmai_err1("VIDIOC_G_FMT failed (%s)\n", strerror(errno));
        return Dmai_EFAIL;
    }

    Dmai_clear(req);
    req.count  = numBufs;
    req.type   = type;
    req.memory = V4L2_MEMORY_MMAP;

    /* Allocate buffers in the capture device driver */
    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
        Dmai_err1("VIDIOC_REQBUFS failed (%s)\n", strerror(errno));
        return Dmai_ENOMEM;
    }

    if (req.count < numBufs || !req.count) {
        Dmai_err0("Insufficient device driver buffer memory\n");
        return Dmai_ENOMEM;
    }

    /* Allocate space for buffer descriptors */
    *bufDescsPtr = calloc(numBufs, sizeof(_VideoBufDesc));

    if (*bufDescsPtr == NULL) {
        Dmai_err0("Failed to allocate space for buffer descriptors\n");
        return Dmai_ENOMEM;
    }

    gfxAttrs.dim.width          = fmt.fmt.pix.width;
    gfxAttrs.dim.height         = fmt.fmt.pix.height;
    gfxAttrs.dim.lineLength     = fmt.fmt.pix.bytesperline;
    gfxAttrs.colorSpace         = colorSpace;
    gfxAttrs.bAttrs.reference   = TRUE;

    *hBufTabPtr = BufTab_create(numBufs, fmt.fmt.pix.sizeimage,
                                BufferGfx_getBufferAttrs(&gfxAttrs));

    if (*hBufTabPtr == NULL) {
        return Dmai_ENOMEM;
    }

    for (bufIdx = 0; bufIdx < numBufs; bufIdx++) {
        bufDesc = &(*bufDescsPtr)[bufIdx];

        /* Ask for information about the driver buffer */
        Dmai_clear(bufDesc->v4l2buf);
        bufDesc->v4l2buf.type   = type;
        bufDesc->v4l2buf.memory = V4L2_MEMORY_MMAP;
        bufDesc->v4l2buf.index  = bufIdx;

        if (ioctl(fd, VIDIOC_QUERYBUF, &bufDesc->v4l2buf) == -1) {
            Dmai_err1("Failed VIDIOC_QUERYBUF (%s)\n", strerror(errno));
            return Dmai_EFAIL;
        }

        /* Map the driver buffer to user space */
        virtPtr = mmap(NULL,
                       bufDesc->v4l2buf.length,
                       PROT_READ | PROT_WRITE,
                       MAP_SHARED,
                       fd,
                       bufDesc->v4l2buf.m.offset) + topOffset;

        if (virtPtr == MAP_FAILED) {
            Dmai_err1("Failed to mmap buffer (%s)\n", strerror(errno));
            return Dmai_EFAIL;
        }

        /* Initialize the Buffer with driver buffer information */
        hBuf = BufTab_getBuf(*hBufTabPtr, bufIdx);

        Buffer_setNumBytesUsed(hBuf, fmt.fmt.pix.bytesperline *
                                     fmt.fmt.pix.height);
        Buffer_setUseMask(hBuf, gfxAttrs.bAttrs.useMask);
        Buffer_setUserPtr(hBuf, virtPtr);

        /* Initialize buffer to black */
        _Dmai_blackFill(hBuf);

        Dmai_dbg3("Driver buffer %d mapped to %#x has physical address "
                  "%#lx\n", bufIdx, (Int) virtPtr, Buffer_getPhysicalPtr(hBuf));

        bufDesc->hBuf = hBuf;

        /* Queue buffer in device driver */
        if (ioctl(fd, VIDIOC_QBUF, &bufDesc->v4l2buf) == -1) {
            Dmai_err1("VIODIOC_QBUF failed (%s)\n", strerror(errno));
            return Dmai_EFAIL;
        }
    }

    return Dmai_EOK;
}
Example #11
0
/******************************************************************************
 * appMain
 ******************************************************************************/
Int appMain(Args * args)
{
    Framecopy_Attrs         fcAttrs      = Framecopy_Attrs_DEFAULT;
    BufferGfx_Attrs         gfxAttrs     = BufferGfx_Attrs_DEFAULT;
    Smooth_Attrs            smAttrs      = Smooth_Attrs_DEFAULT;
    Time_Attrs              tAttrs       = Time_Attrs_DEFAULT;
    BufTab_Handle           hCapBufTab   = NULL;
    BufTab_Handle           hDisBufTab   = NULL;
    Display_Handle          hDisplay     = NULL;
    Capture_Handle          hCapture     = NULL;
    Framecopy_Handle        hFc          = NULL;
    Smooth_Handle           hSmooth      = NULL;
    Time_Handle             hTime        = NULL;
    Int                     numFrame     = 0;
    Display_Attrs           dAttrs;
    Capture_Attrs           cAttrs;
    Buffer_Handle           cBuf, dBuf;
    Cpu_Device              device;
    Int                     bufIdx;
    UInt32                  time;
    BufferGfx_Dimensions    dim;
    Int32                   bufSize;
    Int                     ret = Dmai_EOK;

    /* Initialize DMAI */
    Dmai_init();

    if (args->benchmark) {
        hTime = Time_create(&tAttrs);

        if (hTime == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create Time object\n");
            goto cleanup;
        }
    }

    /* Determine which device the application is running on */
    if (Cpu_getDevice(NULL, &device) < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to determine target board\n");
        goto cleanup;
    }

    /* Set the display and capture attributes depending on device */
    switch (device) {
        case Cpu_Device_DM6467:
            dAttrs = Display_Attrs_DM6467_VID_DEFAULT;
            cAttrs = Capture_Attrs_DM6467_DEFAULT;
            break;
        case Cpu_Device_DM365:
        case Cpu_Device_DM368:
            dAttrs = Display_Attrs_DM365_VID_DEFAULT;
            cAttrs = Capture_Attrs_DM365_DEFAULT;
            dAttrs.colorSpace = ColorSpace_YUV420PSEMI;
            cAttrs.colorSpace = dAttrs.colorSpace;
            break;
        case Cpu_Device_OMAPL138:
            dAttrs = Display_Attrs_OMAPL138_VID_DEFAULT;
            cAttrs = Capture_Attrs_OMAPL138_DEFAULT;
            break;
        case Cpu_Device_OMAP3530:
        case Cpu_Device_DM3730:
            dAttrs     = Display_Attrs_O3530_VID_DEFAULT;
            cAttrs     = Capture_Attrs_OMAP3530_DEFAULT;
            dAttrs.colorSpace = cAttrs.colorSpace = ColorSpace_UYVY;
            dAttrs.rotation = 270;
            break;
        default:
            dAttrs = Display_Attrs_DM6446_DM355_VID_DEFAULT;
            cAttrs = Capture_Attrs_DM6446_DM355_DEFAULT;
            break;
    }

    if (args->displayStd != -1) {
        dAttrs.displayStd = args->displayStd;
    }

    if (args->displayDevice) {
        dAttrs.displayDevice = args->displayDevice;
    }

    if (args->displayNumBufs != -1) {
        dAttrs.numBufs = args->displayNumBufs;
    }

    /* Enable cropping in capture driver if selected */
    if (args->width != -1 && args->height != -1 && args->crop) {
        cAttrs.cropX = args->xIn;
        cAttrs.cropY = args->yIn;
        cAttrs.cropWidth = args->width;
        cAttrs.cropHeight = args->height;
    }

    cAttrs.videoInput = args->videoInput;

    if (Capture_detectVideoStd(NULL, &cAttrs.videoStd, &cAttrs) < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to detect capture video standard\n");
        goto cleanup;
    }

    /* The color space of the capture buffers depend on the device */
    gfxAttrs.colorSpace = cAttrs.colorSpace;

    if (VideoStd_getResolution(cAttrs.videoStd, &gfxAttrs.dim.width, 
                                &gfxAttrs.dim.height) < 0) {
        goto cleanup;
    }

    gfxAttrs.dim.lineLength =
        Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width, 
                                              gfxAttrs.colorSpace), 32); 
    gfxAttrs.dim.x = 0;
    gfxAttrs.dim.y = 0;

    if (gfxAttrs.colorSpace == ColorSpace_YUV422PSEMI) {
        bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 2;
    }
    else if (gfxAttrs.colorSpace == ColorSpace_YUV420PSEMI) {
        bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 3 / 2;
    }
    else {
        bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height;
    }

    if (args->captureUalloc) {
        /* Create a table of video buffers to use with the capture device */
        hCapBufTab = BufTab_create(cAttrs.numBufs, bufSize,
                                   BufferGfx_getBufferAttrs(&gfxAttrs));
        if (hCapBufTab == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to allocate contiguous buffers\n");
            goto cleanup;
        }
    }

    /* Create the capture device driver instance */
    hCapture = Capture_create(hCapBufTab, &cAttrs);

    if (hCapture == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create capture device\n");
        goto cleanup;
    }

    /* Create the display device driver instance */
    dAttrs.videoStd = Capture_getVideoStd(hCapture);
    dAttrs.videoOutput = args->videoOutput;

    if (args->displayUalloc) {
        /* Create a table of video buffers to use with the display device */
        hDisBufTab = BufTab_create(dAttrs.numBufs, bufSize,
                                   BufferGfx_getBufferAttrs(&gfxAttrs));

        if (hDisBufTab == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to allocate contiguous buffers\n");
            goto cleanup;
        }
    }

    hDisplay = Display_create(hDisBufTab, &dAttrs);

    if (hDisplay == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create display device\n");
        goto cleanup;
    }

    if (args->smooth) {
        /* Create the smooth job */
        hSmooth = Smooth_create(&smAttrs);

        if (hSmooth == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create smooth job\n");
        }
    }
    else {
        /* Create the frame copy job */
        fcAttrs.accel = args->accel;
        hFc = Framecopy_create(&fcAttrs);

        if (hFc == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create frame copy job\n");
            goto cleanup;
        }
    }

    /*
     * If cropping is not used, alter the dimensions of the captured
     * buffers and position the smaller image inside the full screen.
     */
    if (args->width != -1 && args->height != -1 && !args->crop) {
        for (bufIdx = 0;
             bufIdx < BufTab_getNumBufs(Capture_getBufTab(hCapture));
             bufIdx++) {

            cBuf = BufTab_getBuf(Capture_getBufTab(hCapture), bufIdx);
            BufferGfx_getDimensions(cBuf, &dim);

            dim.width   = args->width;
            dim.height  = args->height;
            dim.x       = args->xIn;
            dim.y       = args->yIn;

            if (BufferGfx_setDimensions(cBuf, &dim) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Input resolution does not fit in capture frame\n");
                goto cleanup;
            }
        }
    }

    /*
     * Alter the dimensions of the display buffers and position
     * the smaller image inside the full screen.
     */
    if (args->width != -1 && args->height != -1) {
        for (bufIdx = 0;
             bufIdx < BufTab_getNumBufs(Display_getBufTab(hDisplay));
             bufIdx++) {

            dBuf = BufTab_getBuf(Display_getBufTab(hDisplay), bufIdx);
            BufferGfx_getDimensions(dBuf, &dim);

            dim.width   = args->width;
            dim.height  = args->height;
            dim.x       = args->xOut;
            dim.y       = args->yOut;

            if (BufferGfx_setDimensions(dBuf, &dim) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Output resolution does not fit in display frame\n");
                goto cleanup;
            }
        }
    }

    if (args->smooth) {
        if (Smooth_config(hSmooth,
                          BufTab_getBuf(Capture_getBufTab(hCapture), 0),
                          BufTab_getBuf(Display_getBufTab(hDisplay), 0)) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to configure smooth job\n");
            goto cleanup;
        }
    }
    else {
        /* Configure the frame copy job */
        if (Framecopy_config(hFc, BufTab_getBuf(Capture_getBufTab(hCapture), 0),
                          BufTab_getBuf(Display_getBufTab(hDisplay), 0)) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to configure frame copy job\n");
            goto cleanup;
        }
    }

    while (numFrame++ < args->numFrames || args->numFrames == 0) {
        if (args->benchmark) {
            if (Time_reset(hTime) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to reset timer\n");
                goto cleanup;
            }
        }

        /* Get a captured frame from the capture device */
        if (Capture_get(hCapture, &cBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get capture buffer\n");
            goto cleanup;
        }

        /* Get a frame from the display device to be filled with data */
        if (Display_get(hDisplay, &dBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get display buffer\n");
            goto cleanup;
        }

        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer delta\n");
                goto cleanup;
            }
        }

        if (args->smooth) {
            /*
             * Remove interlacing artifacts from the captured buffer and
             * store the result in the display buffer.
             */
            if (Smooth_execute(hSmooth, cBuf, dBuf) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to execute smooth job\n");
                goto cleanup;
            }
        }
        else {
            /* Copy the captured buffer to the display buffer */
            if (Framecopy_execute(hFc, cBuf, dBuf) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to execute frame copy job\n");
                goto cleanup;
            }
        }

        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer delta\n");
                goto cleanup;
            }

            printf("Smooth / Framecopy: %uus ", (Uns) time);
        }

        /* Give captured buffer back to the capture device driver */
        if (Capture_put(hCapture, cBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to put capture buffer\n");
            goto cleanup;
        }

        /* Send filled buffer to display device driver to be displayed */
        if (Display_put(hDisplay, dBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to put display buffer\n");
            goto cleanup;
        }

        if (args->benchmark) {
            if (Time_total(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer total\n");
                goto cleanup;
            }

            printf("Frame time: %uus\n", (Uns) time);
        }
    }

cleanup:
    /* Clean up the application */
    if (hSmooth) {
        Smooth_delete(hSmooth);
    }

    if (hFc) {
        Framecopy_delete(hFc);
    }

    if (hCapture) {
        Capture_delete(hCapture);
    }

    if (hDisplay) {
        Display_delete(hDisplay);
    }

    if (hTime) {
        Time_delete(hTime);
    }

    if (hCapBufTab) {
        BufTab_delete(hCapBufTab);
    }

    if (hDisBufTab) {
        BufTab_delete(hDisBufTab);
    }

    if (ret == Dmai_EFAIL)
        return 1;
    else
        return 0;
}
Example #12
0
/******************************************************************************
 * appMain
 ******************************************************************************/
Int appMain(Args * args)
{
    IMGDEC1_Params          params       = Idec1_Params_DEFAULT;
    IMGDEC1_DynamicParams   dynParams    = Idec1_DynamicParams_DEFAULT;
    Buffer_Attrs            bAttrs       = Buffer_Attrs_DEFAULT;
    BufferGfx_Attrs         gfxAttrs     = BufferGfx_Attrs_DEFAULT;
    Time_Attrs              tAttrs       = Time_Attrs_DEFAULT;   
    Idec1_Handle            hId          = NULL;
    Engine_Handle           hEngine      = NULL;
    Time_Handle             hTime        = NULL;
    Buffer_Handle           hInBuf       = NULL;
    Buffer_Handle           hOutBuf      = NULL;
    FILE                   *outFile      = NULL;
    FILE                   *inFile       = NULL;
    Int                     numBytes     = 0;
    Int                     ret          = Dmai_EOK;
    Cpu_Device              device;
    UInt32                  time;

    printf("Starting application...\n");
     
    if (args->benchmark) {
        hTime = Time_create(&tAttrs);

        if (hTime == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to create Time object\n");
            goto cleanup;
        }
    }

    /* Initialize the codec engine run time */
    CERuntime_init();

    /* Initialize DMAI */
    Dmai_init();

    /* Determine which device the application is running on */
    if (Cpu_getDevice(NULL, &device) < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to determine target board\n");
        goto cleanup;
    }

    /* Open input file */
    inFile = fopen(args->inFile, "rb");

    if (inFile == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open file %s\n", args->inFile);
        goto cleanup;
    }
    
    /* Open output file */
    outFile = fopen(args->outFile, "wb");
    
    if (outFile == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create output file %s\n", args->outFile);
        goto cleanup;
    }

    /* Using a larger vbuf to enhance performance of file i/o */
    if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to setvbuf on file descriptor\n");
        goto cleanup;   
    }
    
    /* Open the codec engine */
    hEngine = Engine_open(args->engineName, NULL, NULL);

    if (hEngine == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open codec engine %s\n", args->engineName);
        goto cleanup;
    }

    /*
     * Set output color format to UYVY or Planar output.
     * Here XDM_DEFUALT sets the output planar format to
     * the planar fromat of the encoded image.
     *           
     */
    switch (args->oColorSpace) {
        case ColorSpace_UYVY:
            params.forceChromaFormat = XDM_YUV_422ILE;
            break;
        case ColorSpace_NOTSET:
            params.forceChromaFormat = XDM_CHROMAFORMAT_DEFAULT;
            break;
        case ColorSpace_YUV444P:
            params.forceChromaFormat = XDM_YUV_444P;
            break;
        case ColorSpace_YUV422P:
            params.forceChromaFormat = XDM_YUV_422P;
            break;
        case ColorSpace_YUV420P:
            params.forceChromaFormat = XDM_YUV_420P;
            break;
        case ColorSpace_YUV420PSEMI:
            params.forceChromaFormat = XDM_YUV_420SP;
            break;
        case ColorSpace_GRAY:
            params.forceChromaFormat = ColorSpace_GRAY;
            break;
        default:
            ret = Dmai_EFAIL;
            fprintf(stderr,"Unsupported output color space %d.\n", args->oColorSpace);
            goto cleanup;
    }

    if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) {
        params.maxHeight = VideoStd_720P_HEIGHT;
        params.maxWidth  = VideoStd_720P_WIDTH;
    }

    if (device == Cpu_Device_DM6467) {
        params.maxHeight = VideoStd_720P_HEIGHT;
        params.maxWidth  = VideoStd_720P_WIDTH;
    }

    /* Create the image decoder */
    hId = Idec1_create(hEngine, args->codecName, &params, &dynParams);

    if (hId == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create image decoder: %s\n", args->codecName);
        goto cleanup;
    }

    /* Align buffers to cache line boundary */    
    gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; 
    
    /* Use cached buffers if requested */    
    if (args->cache) {
        gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags 
            = Memory_CACHED;
    } 
    
    gfxAttrs.colorSpace     = args->oColorSpace;
    gfxAttrs.dim.width      = params.maxWidth;
    gfxAttrs.dim.height     = params.maxHeight;
    gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(params.maxWidth,
                                                       gfxAttrs.colorSpace);
    
    /* Create an output buffer for decoded data */
    hOutBuf = Buffer_create(
        Dmai_roundUp(Idec1_getOutBufSize(hId), BUFSIZEALIGN), 
        BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hOutBuf == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create contiguous buffers\n");
        goto cleanup;
    }

    /* Create an input buffer for encoded data */
    hInBuf = Buffer_create(Dmai_roundUp(Idec1_getInBufSize(hId), BUFSIZEALIGN), 
        &bAttrs);

    if (hInBuf == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to create contiguous buffers\n");
        goto cleanup;
    }
   
    /* Read encoded image data */
    numBytes = fread(Buffer_getUserPtr(hInBuf), 1,
                     Idec1_getInBufSize(hId), inFile);
                     
    Buffer_setNumBytesUsed(hInBuf, numBytes);

    if (args->benchmark) {
        if (Time_reset(hTime) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to reset timer\n");
            goto cleanup;
        }
    }

    if (args->cache) {
        /*  
         *  To meet xDAIS DMA Rule 7, when input buffers are cached, we 
         *  must writeback the cache into physical memory.  Also, per DMA 
         *  Rule 7, we must invalidate the output buffer from
         *  cache before providing it to any xDAIS algorithm.
         */
        Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf));
        /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
        Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf));
        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer delta\n");
                goto cleanup;
            }
    
            printf("Pre-process cache maintenance: %uus \n", (Uns) time);
        }
    }

    printf("Decoding image...\n");
        
    /* Decode the image frame */
    ret = Idec1_process(hId, hInBuf, hOutBuf);
    
    if (ret < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to decode image buffer\n");
        goto cleanup;
    }
    
    if (args->benchmark) {
        if (Time_delta(hTime, &time) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get timer delta\n");
            goto cleanup;
        }
    
        printf("Frame - Decode: %uus \n", (unsigned int)time);
    }
    
    if (args->cache) {
        /* Writeback the outBuf. */
        Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf));
    
        if (args->benchmark) {
            if (Time_delta(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer delta\n");
                goto cleanup;
            }
    
            printf("Post-process cache write back: %uus ", (Uns) time);
        }
    }

    /* Write decoded image to a file */
   if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_UYVY){
        if (writeFrameUYVY(hOutBuf, outFile) < 0) {
           ret = Dmai_EFAIL;
           fprintf(stderr,"Failed to write image to file\n");
           goto cleanup; 
       }
    } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420PSEMI) {
        if (writeFrameSemiPlanar(hOutBuf, outFile) < 0) {
           ret = Dmai_EFAIL;
           fprintf(stderr,"Failed to write image to file\n");
           goto cleanup; 
       }
    }
    else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420P
             || ColorSpace_YUV422P || ColorSpace_YUV444P || ColorSpace_GRAY){
        /* For XDM_GRAY ignoring the color planes */
        if (args->oColorSpace == ColorSpace_GRAY){
            BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); 
        }        
        if (writeFramePlanar(hOutBuf, outFile) < 0) {
           ret = Dmai_EFAIL;
           fprintf(stderr,"Failed to write image to file\n");
           goto cleanup; 
       }
    }
    else {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Invalid output colorspace.\n");
        goto cleanup;     
    }

    if (args->benchmark) {
        if (Time_total(hTime, &time) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get timer total\n");
            goto cleanup;
        }
    
        printf("Total: %uus\n", (unsigned int)time);
    }
       
cleanup:
    /* Clean up the application */
    if (hId) {
        Idec1_delete(hId);
    }
    
    if (hInBuf) {
        Buffer_delete(hInBuf);
    }

    if (hOutBuf) {
        Buffer_delete(hOutBuf);
    }

    if (hEngine) {
        Engine_close(hEngine);
    }

    if (hTime) {
        Time_delete(hTime);
    }

    if (inFile) {
        fclose(inFile);
    }
 
    if (outFile) {
        fclose(outFile);
    }
    
    printf("End of application.\n");

    if (ret == Dmai_EFAIL) 
        return 1;
    else    
        return 0;
}
Example #13
0
/******************************************************************************
 * gst_tiprepencbuf_set_caps
 *****************************************************************************/
static gboolean
gst_tiprepencbuf_set_caps(GstBaseTransform * trans, GstCaps * in,
    GstCaps * out)
{
    GstTIPrepEncBuf *prepencbuf = GST_TIPREPENCBUF(trans);
    BufferGfx_Attrs  gfxAttrs   = BufferGfx_Attrs_DEFAULT;
    gboolean         ret        = FALSE;
    guint32          fourcc;
    guint            outBufSize;

    GST_LOG("begin set caps\n");

    /* parse input cap */
    if (!gst_tiprepencbuf_parse_caps(in, &prepencbuf->srcWidth,
        &prepencbuf->srcHeight, &fourcc)) {
        GST_ELEMENT_ERROR(prepencbuf, RESOURCE, FAILED,
                          ("failed to get input resolution\n"), (NULL));
        goto exit;
    }

    GST_LOG("input fourcc %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(fourcc));

    /* map fourcc with its corresponding dmai colorspace type */
    prepencbuf->srcColorSpace = gst_tiprepencbuf_get_colorSpace(fourcc);

    /* parse output cap */
    if (!gst_tiprepencbuf_parse_caps(out, &prepencbuf->dstWidth,
        &prepencbuf->dstHeight, &fourcc)) {
        GST_ELEMENT_ERROR(prepencbuf, RESOURCE, FAILED,
                          ("failed to get output resolution\n"), (NULL));
        goto exit;
    }

    GST_LOG("output fourcc %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(fourcc));

    /* map fourcc with its corresponding dmai colorspace type */
    prepencbuf->dstColorSpace = gst_tiprepencbuf_get_colorSpace(fourcc);

    /* calculate output buffer size */
    outBufSize = gst_ti_calc_buffer_size(prepencbuf->dstWidth,
                     prepencbuf->dstHeight, 0, prepencbuf->dstColorSpace);

    /* allocate output buffer */
    gfxAttrs.bAttrs.useMask = gst_tidmaibuffer_GST_FREE;
    gfxAttrs.colorSpace     = prepencbuf->dstColorSpace;
    gfxAttrs.dim.width      = prepencbuf->dstWidth;
    gfxAttrs.dim.height     = prepencbuf->dstHeight;
    gfxAttrs.dim.lineLength = 
        BufferGfx_calcLineLength(gfxAttrs.dim.width, gfxAttrs.colorSpace);

    if (prepencbuf->numOutputBufs == 0) {
        prepencbuf->numOutputBufs = 2;
    }

    prepencbuf->hOutBufTab = gst_tidmaibuftab_new(prepencbuf->numOutputBufs,
        outBufSize, BufferGfx_getBufferAttrs (&gfxAttrs));

    if (prepencbuf->hOutBufTab == NULL) {
        GST_ELEMENT_ERROR(prepencbuf, RESOURCE, NO_SPACE_LEFT,
            ("failed to create output bufTab\n"), (NULL));
        goto exit;
    }

    ret = TRUE;

exit:
    GST_LOG("end set caps\n");
    return ret;
}
Example #14
0
/*****************************************************************************
 * gst_tidmaiaccel_prepare_output_buffer
 *    Function is used to allocate output buffer
 *****************************************************************************/
static GstFlowReturn gst_tidmaiaccel_prepare_output_buffer (GstBaseTransform
    *trans, GstBuffer *inBuf, gint size, GstCaps *caps, GstBuffer **outBuf)
{
    GstTIDmaiaccel *dmaiaccel = GST_TIDMAIACCEL(trans);
    Buffer_Handle   hOutBuf;
    Bool isContiguous = FALSE;
    UInt32 phys = 0;

    /* Always check if the buffer is contiguous */
    phys = Memory_getBufferPhysicalAddress(
                    GST_BUFFER_DATA(inBuf),
                    GST_BUFFER_SIZE(inBuf),
                    &isContiguous);

    if (isContiguous && dmaiaccel->width){
        GST_DEBUG("Is contiguous video buffer");

        Memory_registerContigBuf((UInt32)GST_BUFFER_DATA(inBuf),
            GST_BUFFER_SIZE(inBuf),phys);
        /* This is a contiguous buffer, create a dmai buffer transport */
        BufferGfx_Attrs gfxAttrs    = BufferGfx_Attrs_DEFAULT;

        gfxAttrs.bAttrs.reference   = TRUE;
        gfxAttrs.dim.width          = dmaiaccel->width;
        gfxAttrs.dim.height         = dmaiaccel->height;
        gfxAttrs.colorSpace         = dmaiaccel->colorSpace;
        gfxAttrs.dim.lineLength     = dmaiaccel->lineLength;

        hOutBuf = Buffer_create(GST_BUFFER_SIZE(inBuf), &gfxAttrs.bAttrs);
        BufferGfx_setDimensions(hOutBuf,&gfxAttrs.dim);
        BufferGfx_setColorSpace(hOutBuf,gfxAttrs.colorSpace);
        Buffer_setUserPtr(hOutBuf, (Int8*)GST_BUFFER_DATA(inBuf));
        Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf));
        *outBuf = gst_tidmaibuffertransport_new(hOutBuf, NULL, NULL, FALSE);
        gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf),
            Buffer_getSize(hOutBuf));
        gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL);
        gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad));

        /* We need to grab a reference to the input buffer since we have 
         * a pointer to his buffer */
        gst_buffer_ref(inBuf);

        gst_tidmaibuffertransport_set_release_callback(
            (GstTIDmaiBufferTransport *)*outBuf,
            dmaiaccel_release_cb,inBuf);

        return GST_FLOW_OK;
    } else {
        GST_DEBUG("Copying into contiguous video buffer");
        /* This is a contiguous buffer, create a dmai buffer transport */
        if (!dmaiaccel->bufTabAllocated){
            /* Initialize our buffer tab */
            BufferGfx_Attrs gfxAttrs    = BufferGfx_Attrs_DEFAULT;

            gfxAttrs.dim.width          = dmaiaccel->width;
            gfxAttrs.dim.height         = dmaiaccel->height;
            gfxAttrs.colorSpace         = dmaiaccel->colorSpace;
            gfxAttrs.dim.lineLength     = dmaiaccel->lineLength;

            dmaiaccel->hOutBufTab =
                        BufTab_create(2, GST_BUFFER_SIZE(inBuf),
                            BufferGfx_getBufferAttrs(&gfxAttrs));
            pthread_mutex_init(&dmaiaccel->bufTabMutex, NULL);
            pthread_cond_init(&dmaiaccel->bufTabCond, NULL);
            if (dmaiaccel->hOutBufTab == NULL) {
                GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL),
                    ("failed to create output buffer tab"));
                return GST_FLOW_ERROR;
            }
            dmaiaccel->bufTabAllocated = TRUE;
        }

        pthread_mutex_lock(&dmaiaccel->bufTabMutex);
        hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab);
        if (hOutBuf == NULL) {
            GST_INFO("Failed to get free buffer, waiting on bufTab\n");
            pthread_cond_wait(&dmaiaccel->bufTabCond, &dmaiaccel->bufTabMutex);

            hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab);

            if (hOutBuf == NULL) {
                GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL),
                    ("failed to get a free contiguous buffer from BufTab"));
                pthread_mutex_unlock(&dmaiaccel->bufTabMutex);
                return GST_FLOW_ERROR;
            }
        }
        pthread_mutex_unlock(&dmaiaccel->bufTabMutex);

        memcpy(Buffer_getUserPtr(hOutBuf),GST_BUFFER_DATA(inBuf),
            GST_BUFFER_SIZE(inBuf));
        Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf));
        *outBuf = gst_tidmaibuffertransport_new(hOutBuf, &dmaiaccel->bufTabMutex,
            &dmaiaccel->bufTabCond, FALSE);
        gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf),
            Buffer_getSize(hOutBuf));
        gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL);
        gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad));

        return GST_FLOW_OK;
    }
}
Example #15
0
/*******************************************************************************
 * gst_tidmaivideosink_render
*******************************************************************************/
static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink,
                         GstBuffer * buf)
{
    BufferGfx_Attrs       gfxAttrs  = BufferGfx_Attrs_DEFAULT;
    Buffer_Handle         hDispBuf  = NULL;
    Buffer_Handle         inBuf     = NULL;
    BufferGfx_Dimensions  inDimSave;
    GstTIDmaiVideoSink   *sink      = GST_TIDMAIVIDEOSINK_CAST(bsink);

    GST_DEBUG("Begin, buffer %p",buf);

    /* The base sink send us the first buffer twice, so we avoid processing 
     * it again, since the Display_put may fail on this case when using 
     * pad_allocation 
     */
    if (sink->prerolledBuffer == buf){
        GST_DEBUG("Not displaying previously pre-rolled buffer");
        sink->prerolledBuffer = NULL;
        return GST_FLOW_OK;
    }
    sink->prerolledBuffer = NULL;

    /* If the input buffer is non dmai buffer, then allocate dmai buffer and
     *  copy input buffer in dmai buffer using memcpy routine.
     */
    if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) {
        inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf);
    } else {
        /* allocate DMAI buffer */
        if (sink->tempDmaiBuf == NULL) {

            GST_DEBUG("Input buffer is non-dmai, allocating new buffer");
            gfxAttrs.dim.width          = sink->width;
            gfxAttrs.dim.height         = sink->height;
            gfxAttrs.dim.lineLength     = BufferGfx_calcLineLength(sink->width,
                                            sink->colorSpace);
            gfxAttrs.colorSpace         = sink->colorSpace;
            sink->tempDmaiBuf           = Buffer_create(GST_BUFFER_SIZE(buf),
                                           BufferGfx_getBufferAttrs(&gfxAttrs));

            if (sink->tempDmaiBuf == NULL) {
                GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL),
                    ("Failed to allocate memory for the input buffer"));
                return GST_FLOW_UNEXPECTED;
            }
        }
        inBuf = sink->tempDmaiBuf;

        memcpy(Buffer_getUserPtr(inBuf), buf->data, buf->size);
    }

    if (Buffer_getBufTab(inBuf) == Display_getBufTab(sink->hDisplay)) {
        GST_DEBUG("Flipping pad allocated buffer");
        /* We got a buffer that is already on video memory, just flip it */
        hDispBuf = inBuf;
        if (sink->numAllocatedBuffers)
            sink->numAllocatedBuffers--;
        sink->allocatedBuffers[Buffer_getId(inBuf)] = NULL;
        if (buf == sink->lastAllocatedBuffer){
            sink->lastAllocatedBuffer = NULL;
        }
    } else {
        /* Check if we can allocate a new buffer, otherwise we may need 
         * to drop the buffer
         */
        BufferGfx_getDimensions(inBuf, &inDimSave);
        if ((sink->numAllocatedBuffers >= 
             (BufTab_getNumBufs(Display_getBufTab(sink->hDisplay)) - 1)) &&
             (sink->numUnusedBuffers == 0)){
            GST_ELEMENT_WARNING(sink,RESOURCE,NO_SPACE_LEFT,(NULL),
                ("Dropping incoming buffers because no display buffer"
                    " available"));
            return GST_FLOW_OK;
        } else {
            GST_DEBUG("Obtaining display buffer");
            hDispBuf = gst_tidmaivideosink_get_display_buffer(sink,inBuf);
            if (!hDispBuf){
                return GST_FLOW_UNEXPECTED;
            }
        }

        if (Framecopy_config(sink->hFc, inBuf, hDispBuf) < 0) {
            GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL),
                ("Failed to configure the frame copy"));
            return GST_FLOW_UNEXPECTED;
        }

        if (Framecopy_execute(sink->hFc, inBuf, hDispBuf) < 0) {
            GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL),
                ("Failed to execute the frame copy"));
            return GST_FLOW_UNEXPECTED;
        }

        BufferGfx_resetDimensions(hDispBuf);
        BufferGfx_setDimensions(inBuf, &inDimSave);
    }

    /* Send filled buffer to display device driver to be displayed */
    if (Display_put(sink->hDisplay, hDispBuf) < 0) {
        GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL),
            ("Failed to put the buffer on display"));
        return GST_FLOW_UNEXPECTED;
    }

    GST_DEBUG("Finish");

    return GST_FLOW_OK;
}
Example #16
0
/******************************************************************************
 * appMain
 ******************************************************************************/
Int appMain(Args * args)
{
    Time_Attrs           tAttrs    = Time_Attrs_DEFAULT;
    BufferGfx_Attrs      gfxAttrs  = BufferGfx_Attrs_DEFAULT;
    Display_Handle       hDisplay  = NULL;
    Time_Handle          hTime     = NULL;
    BufTab_Handle        hDisBufTab= NULL;
    Int                  numFrame  = 0;
    Display_Attrs        dAttrs;
    Buffer_Handle        hDispBuf;
    Int                  y, x, pos, color;
    Cpu_Device           device;
    UInt32               time;
    Int32                bufSize;
    BufferGfx_Dimensions dim;
    Int                  ret = Dmai_EOK;

    /* Initialize DMAI */
    Dmai_init();

    if (args->benchmark) {
        hTime = Time_create(&tAttrs);

        if (hTime == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr, "Failed to create Time object\n");
            goto cleanup;
        }
    }

    /* Determine which device the application is running on */
    if (Cpu_getDevice(NULL, &device) < 0) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to determine target board\n");
        goto cleanup;
    }

    switch (device) {
        case Cpu_Device_DM6467:
            dAttrs = Display_Attrs_DM6467_VID_DEFAULT;
            break;
        case Cpu_Device_OMAP3530:
        case Cpu_Device_DM3730:
            dAttrs = Display_Attrs_O3530_VID_DEFAULT;
            break;
        case Cpu_Device_OMAPL138:
            dAttrs = Display_Attrs_OMAPL138_OSD_DEFAULT;
            break;
        case Cpu_Device_DM365:
        case Cpu_Device_DM368:
            dAttrs = Display_Attrs_DM365_VID_DEFAULT;
            break;            
        case Cpu_Device_OMAPL137:
            dAttrs = Display_Attrs_OMAPL137_OSD_DEFAULT;
            break;        
        default:
            dAttrs = Display_Attrs_DM6446_DM355_VID_DEFAULT;
            break;
    }
 
    if (args->displayUalloc) {
        gfxAttrs.colorSpace = dAttrs.colorSpace;

        if (VideoStd_getResolution(args->videoStd, &gfxAttrs.dim.width, 
                                   &gfxAttrs.dim.height) < 0) {
            goto cleanup;
        }

        gfxAttrs.dim.lineLength =
            Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width, 
                                                  gfxAttrs.colorSpace), 32); 

        gfxAttrs.dim.x = 0;
        gfxAttrs.dim.y = 0;

        if (gfxAttrs.colorSpace == ColorSpace_YUV422PSEMI) {
            bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 2;
        }
        else if (gfxAttrs.colorSpace == ColorSpace_YUV420PSEMI) {
            bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 3 / 2;
        }
        else {
            bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height;
        }

        if (bufSize < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to calculated size for display buffers\n");
            goto cleanup;
        }

        /* Create a table of video buffers to use with the display device */
        hDisBufTab = BufTab_create(dAttrs.numBufs, bufSize,
                                   BufferGfx_getBufferAttrs(&gfxAttrs));

        if (hDisBufTab == NULL) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to allocate contiguous buffers\n");
            goto cleanup;
        }
    }

    /* Create the video display */
    dAttrs.videoStd = args->videoStd;
    dAttrs.videoOutput = args->videoOutput;
    hDisplay = Display_create(hDisBufTab, &dAttrs);

    if (hDisplay == NULL) {
        ret = Dmai_EFAIL;
        fprintf(stderr,"Failed to open display device\n");
        goto cleanup;
    }

    x = color = 0;

    while (numFrame++ < args->numFrames) {
        if (args->benchmark) {
            if (Time_reset(hTime) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to reset timer\n");
                goto cleanup;
            }
        }

        /* Get a buffer from the display driver */
        if (Display_get(hDisplay, &hDispBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to get display buffer\n");
            goto cleanup;
        }

        /* Retrieve the dimensions of the display buffer */
        BufferGfx_getDimensions(hDispBuf, &dim);

        printf("Display size %dx%d pitch %d x = %d color %d\n", (Int) dim.width,
               (Int) dim.height, (Int) dim.lineLength, x, color);

        /* Draw a vertical bar of a color */
        for (y = 0; y < dim.height; y++) {
            pos = y * dim.lineLength + x * 2;
            memset(Buffer_getUserPtr(hDispBuf) + pos, color, 2);
        }

        x = (x + 1) % dim.width;
        color = (color + 1) % 0xff;

        /* Give the display buffer back to be displayed */
        if (Display_put(hDisplay, hDispBuf) < 0) {
            ret = Dmai_EFAIL;
            fprintf(stderr,"Failed to put display buffer\n");
            goto cleanup;
        }

        if (args->benchmark) {
            if (Time_total(hTime, &time) < 0) {
                ret = Dmai_EFAIL;
                fprintf(stderr,"Failed to get timer total\n");
                goto cleanup;
            }

            printf("[%d] Frame time: %uus\n", numFrame, (Uns) time);
        }
    }

cleanup:
    /* Clean up the application */
    if (hDisplay) {
        Display_delete(hDisplay);
    }

    if (hDisBufTab) {
        BufTab_delete(hDisBufTab);
    }
    
    if (hTime) {
        Time_delete(hTime);
    }

    if (ret == Dmai_EFAIL)
        return 1;
    else
        return 0;
}
Example #17
0
Void *videoThrFxn(Void *arg)
{
	VideoEnv *envp = (VideoEnv *) arg;

	Venc1_Handle hVe1 = NULL;
	VIDENC1_Params params = Venc1_Params_DEFAULT;
	VIDENC1_DynamicParams dynParams = Venc1_DynamicParams_DEFAULT;
	IH264VENC_Params h264Params = IH264VENC_PARAMS;
	IH264VENC_DynamicParams h264DynParams = H264VENC_TI_IH264VENC_DYNAMICPARAMS;
	VUIParamBuffer VUI_Buffer = H264VENC_TI_VUIPARAMBUFFER;

	BufTab_Handle hVidBufTab = NULL;
	Buffer_Handle hVInBuf, hWOutBuf;
	BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;

	ColorSpace_Type colorSpace = ColorSpace_YUV420PSEMI;

	Int bufSize = 0;

	Void *status = THREAD_SUCCESS;

	/* Initialization */
	params.maxWidth = envp->imageWidth;
	params.maxHeight = envp->imageHeight;
	params.inputChromaFormat = XDM_YUV_420SP;
	params.reconChromaFormat = XDM_YUV_420SP;
	params.maxFrameRate = envp->videoFrameRate;
	params.encodingPreset = XDM_USER_DEFINED;
	params.rateControlPreset = IVIDEO_USER_DEFINED;
	params.maxBitRate = 10000000;

	dynParams.targetBitRate = envp->videoBitRate*0.9;
	dynParams.inputWidth = envp->imageWidth;
	dynParams.captureWidth = Dmai_roundUp(BufferGfx_calcLineLength(envp->imageWidth, colorSpace), 32);
	dynParams.inputHeight = envp->imageHeight;
	dynParams.refFrameRate = params.maxFrameRate;
	dynParams.targetFrameRate = params.maxFrameRate;
	dynParams.intraFrameInterval = 0;
	dynParams.interFrameInterval = 0;

	h264Params.videncParams = params;
	h264Params.videncParams.size = sizeof(IH264VENC_Params);
	h264Params.encQuality = 1;
	h264Params.enableDDRbuff = 1; /* Uses DDR instead of VICP buffers */
	h264Params.enableARM926Tcm = 0;
	h264Params.enableVUIparams = (0x1 << 1);
	h264Params.videncParams.inputContentType = IVIDEO_PROGRESSIVE;

	h264DynParams.videncDynamicParams = dynParams;
	h264DynParams.videncDynamicParams.size = sizeof(IH264VENC_DynamicParams);

	h264DynParams.VUI_Buffer = &VUI_Buffer;
	h264DynParams.VUI_Buffer->aspectRatioInfoPresentFlag = 1;
	h264DynParams.VUI_Buffer->overscanInfoPresentFlag = 0;
	h264DynParams.VUI_Buffer->videoSignalTypePresentFlag = 0;
	h264DynParams.VUI_Buffer->timingInfoPresentFlag = 1;
	h264DynParams.VUI_Buffer->numUnitsInTicks = 1;
	h264DynParams.VUI_Buffer->timeScale = params.maxFrameRate / 1000;
	h264DynParams.VUI_Buffer->fixedFrameRateFlag = 1; 
	h264DynParams.VUI_Buffer->nalHrdParameterspresentFlag = 1;
	h264DynParams.VUI_Buffer->picStructPresentFlag = 1;

	h264DynParams.idrFrameInterval = 15;

	hVe1 = Venc1_create(envp->hEngine, envp->videoEncoder,
			(IVIDENC1_Params *) &h264Params,
			(IVIDENC1_DynamicParams *) &h264DynParams);
	if (hVe1 == NULL) {
		ERR("Failed to create video encoder: %s\n", envp->videoEncoder);
		cleanup(THREAD_FAILURE);
	}

	/* Store the output buffer size in the environment */
	envp->outBufSize = Venc1_getOutBufSize(hVe1);

	/* Signal that the codec is created and output buffer size available */
	Rendezvous_meet(envp->hRendezvousWriter);

	/* Video BufTab create */
	BufferGfx_calcDimensions(VideoStd_D1_PAL, colorSpace, &gfxAttrs.dim);
	gfxAttrs.dim.width = 704;
	gfxAttrs.dim.height = 576;
	gfxAttrs.dim.lineLength = Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width, colorSpace), 32);
	gfxAttrs.colorSpace = colorSpace;
	bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 3 / 2;
	hVidBufTab = BufTab_create(NUM_VIDEO_BUFS, bufSize, BufferGfx_getBufferAttrs(&gfxAttrs));
	if (hVidBufTab == NULL) {
		ERR("Failed to create video buftab\n");
		cleanup(THREAD_FAILURE);
	}

	/* Set input buffer table */
    Venc1_setBufTab(hVe1, hVidBufTab);

	/* Send video buffers to DEI */
	Int nBufId = 0;
	for (nBufId = 0; nBufId < NUM_VIDEO_BUFS; nBufId++) {
		hVInBuf = BufTab_getBuf(hVidBufTab, nBufId);
		if (Fifo_put(envp->hVideoOutFifo, hVInBuf) < 0) {
			ERR("Failed to send buffer to dei thread\n");
			cleanup(THREAD_FAILURE);
		}
	}

	/* Signal that initialization is done and wait for other threads */
	Rendezvous_meet(envp->hRendezvousInit);

	while(1) {

		/* Get buffer from DEI thread */
		if(Fifo_get(envp->hVideoInFifo, &hVInBuf) < 0) {
			ERR("Failed to get buffer from dei thread\n");
			cleanup(THREAD_FAILURE);
		}

		/* Get buffer from Writer thread */
		if(Fifo_get(envp->hWriterOutFifo, &hWOutBuf) < 0) {
			ERR("Failed to get buffer from writer thread\n");
			cleanup(THREAD_FAILURE);
		}

		/* Make sure the whole buffer is used for input */
		BufferGfx_resetDimensions(hVInBuf);

		/* Encode */
		if (Venc1_process(hVe1, hVInBuf, hWOutBuf) < 0) {
			ERR("Failed to encode video buffer\n");
			cleanup(THREAD_FAILURE);
		}

		/* Put buffer to dei thread */
		if (Fifo_put(envp->hVideoOutFifo, hVInBuf) < 0) {
			ERR("Failed to send buffer to dei thread\n");
			cleanup(THREAD_FAILURE);
		}

		/* Put buffer to writer thread */
		if (Fifo_put(envp->hWriterInFifo, hWOutBuf) < 0) {
			ERR("Failed to send buffer to dei thread\n");
			cleanup(THREAD_FAILURE);
		}

	}

cleanup:

	/* Make sure the other threads aren't waiting for us */
	Rendezvous_force(envp->hRendezvousInit);
	Rendezvous_force(envp->hRendezvousWriter);

	/* Make sure the other threads aren't waiting for init to complete */
	Rendezvous_meet(envp->hRendezvousCleanup);

	if (hVidBufTab) {
		BufTab_delete(hVidBufTab);
	}

	if (hVe1) {
		Venc1_delete(hVe1);
	}

	return status;
}