工具/软件:
您好、
我们正在 Gstreamer 流水线中使用 edgeai-gst-plugins 与 OpenVX 和 v4l2h265enc。 当 v4l2h265enc 使用 dma-buf 导入时、我们注意到图像损坏。 我们的“简化“流程:
gst-launch-1.0 videotestsrc pattern=SMPTE num-buffers=30 ! video/x-raw、格式=NV12、宽度=1920、高度=1080、帧速率=30/1! tiovxmultiscaler ! video/x-raw、格式=NV12、宽度=1280、高度=720、帧速率=30/1 ! 我们的自定义元素! tiovxmemalloc! video/x-raw、strip-y-align=32! v4l2h265enc output-io-mode=5! h265parse! mp4mux! filesink location=/tmp/out.mp4 sync=false -v
通过这一流水线、我们可以看到图像损坏、如下所示:

损坏模式不一致、并且会因帧而异。 这看起来像是缓存一致性问题。 但是、不使用 dma-buf 导入 (output-IO-mode=0) 的流水线可以正常工作。 但这会导致视频帧复制、出于性能原因、我们需要避免该复制。
gst-launch-1.0 videotestsrc pattern=SMPTE num-buffers=30 ! video/x-raw、格式=NV12、宽度=1920、高度=1080、帧速率=30/1! tiovxmultiscaler ! video/x-raw、格式=NV12、宽度=1280、高度=720、帧速率=30/1 ! 我们的自定义元素! tiovxmemalloc! video/x-raw、strip-y-align=32! v4l2h265enc output-io-mode=0! h265parse! mp4mux! filesink location=/tmp/out.mp4 sync=false -v

our_custom_Element:在这种情况下、我们的自定义 GStreamer 元素非常简单。 它只是从缓冲区中获取 vx_image、映射它、设置内容、然后取消映射它。 下面是展示该损坏情况的示例代码。 在工作和非工作的情况下,我们的自定义元素是相同的。 仅当 v4l2h265enc output-io-mode=5 时才会发生损坏。
static GstFlowReturn gst_tiovx_custom_transform_ip(GstBaseTransform *trans, GstBuffer *buf)
{
auto self{trans};
vx_uint32 constexpr OVX_ARRAY_PRIMARY_IMAGE_INDEX{0};
auto meta{reinterpret_cast<GstTIOVXImageMeta *>(gst_buffer_get_meta(buf, GST_TYPE_TIOVX_IMAGE_META_API))};
if (not meta)
{
GST_ERROR("gst_buffer_get_meta failed: GstTIOVXImageMeta missing!");
return GST_FLOW_ERROR;
}
vx_reference fullImageReference{vxGetObjectArrayItem(meta->array, OVX_ARRAY_PRIMARY_IMAGE_INDEX)};
if (not fullImageReference) {
GST_ELEMENT_ERROR(self, STREAM, FAILED, ("vxGetObjectArrayItem failed"), (NULL));
return GST_FLOW_ERROR;
}
const int patchX = 320;
const int patchY = 180;
vx_image fullImage{reinterpret_cast<vx_image>(fullImageReference)};
vx_rectangle_t const rect = {patchX, patchY, patchX*3, patchY*3};
vx_map_id map_id{};
void *ptr{nullptr};
vx_imagepatch_addressing_t addr{};
for (vx_uint32 plane{0}; plane < NV12_PLANE_COUNT; ++plane)
{
if (vxMapImagePatch(fullImage, &rect, plane, &map_id, &addr, &ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X) != VX_SUCCESS)
{
GST_ELEMENT_ERROR(self, STREAM, FAILED, ("vxMapImagePatch failed"), (NULL));
return GST_FLOW_ERROR;
}
auto const yRows{addr.dim_y * addr.scale_y / VX_SCALE_UNITY};
for (vx_uint32 y = 0; y < yRows; y++)
{
vx_uint8 *rowPtr = (vx_uint8 *)ptr + y * addr.stride_y;
auto const xBytes{addr.dim_x * addr.stride_x * addr.scale_x / VX_SCALE_UNITY};
memset(rowPtr, 0,xBytes);
}
if (vxUnmapImagePatch(fullImage, map_id) != VX_SUCCESS)
{
GST_ELEMENT_ERROR(self, STREAM, FAILED, ("vxUnmapImagePatch failed"), (NULL));
return GST_FLOW_ERROR;
}
}
vxReleaseReference (&fullImageReference);
return GST_FLOW_OK;
}您能看看这个并帮助解决问题吗? 是否存在任何互操作性问题? 这里是否有我们为了保持 tiovx 和 DMA buf 一致而错过的任何内容