コード例 #1
0
ファイル: gsttiprepencbuf.c プロジェクト: xieran1988/parents
/******************************************************************************
 * 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;
}
コード例 #2
0
/******************************************************************************
 * 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;
}
コード例 #3
0
ファイル: _VideoBuf.c プロジェクト: NearZhxiAo/3730
/******************************************************************************
 * _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;
}
コード例 #4
0
/******************************************************************************
 * gst_ticircbuffer_get_data
 ******************************************************************************/
GstBuffer* gst_ticircbuffer_get_data(GstTICircBuffer *circBuf)
{
    Buffer_Handle  hCircBufWindow;
    Buffer_Attrs   bAttrs;
    GstBuffer     *result;
    Int32          bufSize;

    if (circBuf == NULL) {
        return NULL;
    }

    /* Reset our mutex condition so calling wait_on_consumer will block */
    Rendezvous_reset(circBuf->waitOnProducer);

    /* Reset the read pointer to the beginning of the buffer when we're
     * approaching the buffer's end (see function definition for reset
     * conditions).
     */
    gst_ticircbuffer_reset_read_pointer(circBuf);

    /* Don't return any data util we have a full window available */
    while (!circBuf->drain && !gst_ticircbuffer_window_available(circBuf)) {

        GST_LOG("blocking output until a full window is available\n");
        gst_ticircbuffer_wait_on_producer(circBuf);
        GST_LOG("unblocking output\n");
        gst_ticircbuffer_reset_read_pointer(circBuf);

        /* Reset our mutex condition so calling wait_on_consumer will block */
        Rendezvous_reset(circBuf->waitOnProducer);
    }

    /* Set the size of the buffer to be no larger than the window size.  Some
     * audio codecs have an issue when you pass a buffer larger than 64K.
     * We need to pass it smaller buffer sizes though, as the EOS is detected
     * when we return a 0 size buffer.
     */
    bufSize = gst_ticircbuffer_data_available(circBuf);
    if (bufSize > circBuf->windowSize) {
        bufSize = circBuf->windowSize;
    }

    /* Return a reference buffer that points to the area of the circular
     * buffer we want to decode.
     */
    Buffer_getAttrs(circBuf->hBuf, &bAttrs);
    bAttrs.reference = TRUE;

    hCircBufWindow = Buffer_create(bufSize, &bAttrs);

    Buffer_setUserPtr(hCircBufWindow, circBuf->readPtr);
    Buffer_setNumBytesUsed(hCircBufWindow, bufSize);

    GST_LOG("returning data at offset %u\n", circBuf->readPtr - 
        Buffer_getUserPtr(circBuf->hBuf));

    result = (GstBuffer*)(gst_tidmaibuffertransport_new(hCircBufWindow, NULL));
    GST_BUFFER_TIMESTAMP(result) = circBuf->dataTimeStamp;
    GST_BUFFER_DURATION(result)  = GST_CLOCK_TIME_NONE;
    return result;
}
コード例 #5
0
ファイル: gsttidmaiaccel.c プロジェクト: sv99/gst-ti-dmai
/*****************************************************************************
 * 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;
    }
}