/****************************************************************************** * gst_tiprepencbuf_transform * Transforms one incoming buffer to one outgoing buffer. *****************************************************************************/ static GstFlowReturn gst_tiprepencbuf_transform(GstBaseTransform * trans, GstBuffer * src, GstBuffer * dst) { GstTIPrepEncBuf *prepencbuf = GST_TIPREPENCBUF(trans); /* If the input buffer is a physically contiguous DMAI buffer, it can * be passed directly to the codec. */ if (GST_IS_TIDMAIBUFFERTRANSPORT(src)) { gst_buffer_unref(dst); dst = gst_buffer_ref(src); return GST_FLOW_OK; } /* Otherwise, copy the buffer contents into our local physically contiguous * DMAI buffer. The gst_tiprepencbuf_copy_input function will copy * using hardware acceleration if possible. */ if (!(gst_tiprepencbuf_copy_input(prepencbuf, GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(dst), src))) { return GST_FLOW_ERROR; } return GST_FLOW_OK; }
/******************************************************************************* * 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; }
/***************************************************************************** * gst_tiprepencbuf_copy_input * Make the input data in src available in the physically contiguous memory * in dst in the best way possible. Preferably an accelerated copy or * color conversion. ****************************************************************************/ static Int gst_tiprepencbuf_copy_input(GstTIPrepEncBuf * prepencbuf, Buffer_Handle hDstBuf, GstBuffer * src) { Framecopy_Attrs fcAttrs = Framecopy_Attrs_DEFAULT; gboolean accel = FALSE; Buffer_Handle hInBuf = NULL; Int ret = -1; #if defined(Platform_dm365) || defined(Platform_dm368) BufferGfx_Dimensions dim; #endif /* Check to see if we need to execute ccv on dm6467 */ if (prepencbuf->device == Cpu_Device_DM6467 && prepencbuf->srcColorSpace == ColorSpace_YUV422PSEMI) { return gst_tiprepencbuf_422psemi_420psemi(hDstBuf, src, prepencbuf); } GST_LOG("gst_tiphyscontig_copy_input - begin\n"); if (prepencbuf->hFc == NULL) { /* Enable the accel framecopy based on contiguousInputFrame. * If accel is set to FALSE then DMAI will use regular memcpy function * else will use HW accelerated framecopy. */ /* If we are getting dmai transport buffer then enable HW * acceleration */ if (GST_IS_TIDMAIBUFFERTRANSPORT(src)) { accel = TRUE; } else { accel = prepencbuf->contiguousInputFrame; } fcAttrs.accel = prepencbuf->contiguousInputFrame; prepencbuf->hFc = Framecopy_create(&fcAttrs); if (prepencbuf->hFc == NULL) { GST_ERROR("failed to create framecopy handle\n"); goto exit; } GST_INFO("HW accel framecopy: %s\n", accel ? "enabled" : "disabled"); } /* Prepare input buffer */ hInBuf = gst_tiprepencbuf_convert_gst_to_dmai(prepencbuf, src, TRUE); if (hInBuf == NULL) { GST_ERROR("failed to get dmai buffer\n"); goto exit; } #if defined(Platform_dm365) || defined(Platform_dm368) /* Handle resizer 32-byte issue on DM365 platform */ if (prepencbuf->device == Cpu_Device_DM365 || prepencbuf->device == Cpu_Device_DM368) { if ((prepencbuf->srcColorSpace == ColorSpace_YUV420PSEMI)) { BufferGfx_getDimensions(hInBuf, &dim); dim.lineLength = Dmai_roundUp(dim.lineLength, 32); BufferGfx_setDimensions(hInBuf, &dim); } } #endif /* Prepare output buffer */ if (Framecopy_config(prepencbuf->hFc, hInBuf, hDstBuf) < 0) { GST_ERROR("failed to configure framecopy\n"); goto exit; } if (Framecopy_execute(prepencbuf->hFc, hInBuf, hDstBuf) < 0) { GST_ERROR("failed to execute framecopy\n"); goto exit; } ret = GST_BUFFER_SIZE(src); exit: if (hInBuf) { Buffer_delete(hInBuf); } GST_LOG("gst_tiprepencbuf_copy_input - end\n"); return ret; }
/****************************************************************************** * gst_tiprepencbuf_422psemi_420psemi * this function color convert YUV422PSEMI to YUV420PSEMI. *****************************************************************************/ static Int gst_tiprepencbuf_422psemi_420psemi(Buffer_Handle hDstBuf, GstBuffer * src, GstTIPrepEncBuf * prepencbuf) { Ccv_Attrs ccvAttrs = Ccv_Attrs_DEFAULT; gboolean accel = FALSE; Buffer_Handle hInBuf = NULL; Int ret = -1; GST_LOG("gst_tiprepencbuf_422psemi_420psemi - begin\n"); /* create ccv handle */ if (prepencbuf->hCcv == NULL) { /* Enable the accel ccv based on contiguousInputFrame. * If accel is set to FALSE then DMAI will use software ccv function * else will use HW accelerated ccv engine. */ /* If we are getting dmai transport buffer then enable HW * acceleration */ if (GST_IS_TIDMAIBUFFERTRANSPORT(src)) { accel = TRUE; } else { accel = prepencbuf->contiguousInputFrame; } ccvAttrs.accel = prepencbuf->contiguousInputFrame; prepencbuf->hCcv = Ccv_create(&ccvAttrs); if (prepencbuf->hCcv == NULL) { GST_ERROR("failed to create CCV handle\n"); goto exit; } GST_INFO("HW accel CCV: %s\n", accel ? "enabled" : "disabled"); } /* Prepare input buffer */ hInBuf = gst_tiprepencbuf_convert_gst_to_dmai(prepencbuf, src, TRUE); if (hInBuf == NULL) { GST_ERROR("failed to get dmai buffer\n"); goto exit; } /* Prepare output buffer */ if (Ccv_config(prepencbuf->hCcv, hInBuf, hDstBuf) < 0) { GST_ERROR("failed to config CCV handle\n"); goto exit; } if (Ccv_execute(prepencbuf->hCcv, hInBuf, hDstBuf) < 0) { GST_ERROR("failed to execute Ccv handle\n"); goto exit; } ret = GST_BUFFER_SIZE(src); GST_LOG("gst_tiprepencbuf_422psemi_420psemi - end\n"); exit: if (hInBuf) { Buffer_delete(hInBuf); } return ret; }