Ticket Name: TDA2HG: how to create a gstreamer source element which can send video frame to ducatih264enc Query Text: Part Number: TDA2HG I create a source element based on pushsrc,but buffer_map failed when linked to ducatih264enc gstreamer links as below: mycamera -> ducatih264enc -> h264parse -> qtmux -> filesink location=test.mp4 test.mp4 contains all solid green color,and gstreamer output error 0:00:01.166878106 928 0x143950 ERROR default video-frame.c:155:gst_video_frame_map_id: failed to map buffer 0:00:01.168804730 928 0x143950 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5d01510: fd 31: mmap failed: Permission denied 0:00:01.168847674 928 0x143950 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5d01510: subclass map failed 0:00:01.168921850 928 0x143950 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5d01810: fd 36: mmap failed: Permission denied 0:00:01.168960077 928 0x143950 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5d01810: subclass map failed is there any example source element which can send data to ducatih264enc ? thanks. Responses: Hi , Please confirm if you are using ProcessorSDK Linux Automotive(PSDKLA) or VisionSDK? If it is PSDKLA, you should be able to use v4l2src to capture and encode with ducatih264enc but if it is visionSDK, VIP is controlled by M4 and v4l2src can not be used. If you are using visionSDK, you should get the captured buffers from M4 to A15 and create a pseudo-source element which pushes buffers to encoder. Thanks RamPrasad hi,thanks for reply. I'm using VisionSDK-3.5, as you say i create a source element based on pushsrc element ( implement set_caps and fill function) , and my custom source element can got capture buffers. But my source element failed to call gst_video_frame_map,gstreamer output error message which in my question. Also i notice that v4l2src enable dmabuf by io-mode property ,but the source code confused me. I dont not know how and when to create dma buf for ducatih264enc in my source element. Hi li, There is one know issue with vmemexp driver that mmap returns 'Permission denied" error. I have confirmed this with this example #include #include #include #include #include #include #include "util.h" struct dmabuf_vmem_export { unsigned long vaddr; unsigned long size; int fd; }; #define DMABUF_CODE 0xDB #define DMABUF_BASE 0xD0 #define DBUFIOC_EXPORT_VIRTMEM _IOWR(DMABUF_CODE, DMABUF_BASE + 0, struct dmabuf_vmem_export) int main(int argc, char **argv) { int fd, file; void *malmem = NULL; void *vmem = NULL; struct dmabuf_vmem_export exp; int memcache; malmem = malloc(1024 * 1024 * 2); printf("Malloc allocated at %p\n", malmem); /* Export different memories */ fd = open("/dev/vmemexp", O_RDWR | O_CLOEXEC); printf("/dev/vmemexp opened, fd = %d\n", fd); exp.fd = -1; exp.vaddr = (unsigned long) malmem; exp.size = 1024 * 1024 * 2; ioctl(fd, DBUFIOC_EXPORT_VIRTMEM, &exp); printf("fd is %d\n", exp.fd); if(malmem) free(malmem); } For this reason gstreamer ducati encoder also is failing when gstreamer software is trying to do mmap. This can be avoid if dma-buf fd is passed to ducati encoder from pseudo-source plugin. I will let you know how to do it. Thanks RamPrasad hi,Ram, thanks for your help. I'll try it and update question if any question. hi,Ram, I update my source element to pseudo-srouce by implement get_time function,but still failed to mmap,output as below memory[0]: is dma buffer 0:00:00.348308047 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c01408: fd 29: mmap failed: Permission denied 0:00:00.348396050 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c01408: subclass map failed 0:00:00.348485191 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c01460: fd 30: mmap failed: Permission denied 0:00:00.348527159 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c01460: subclass map failed 0:00:00.348589460 1602 0x1a82f0 ERROR default video-frame.c:155:gst_video_frame_map_id: failed to map buffer failed to frame_map from gst_cameravpf_get_times framecount: 0 , timeunit: 33333333 pts: 0 dur: 33333333 from gst_cameravpf_fill memory[0]: is dma buffer 0:00:00.356804290 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c01510: fd 33: mmap failed: Permission denied 0:00:00.356851463 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c01510: subclass map failed 0:00:00.356930194 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c01568: fd 34: mmap failed: Permission denied 0:00:00.356969884 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c01568: subclass map failed 0:00:00.357032511 1602 0x1a82f0 ERROR default video-frame.c:155:gst_video_frame_map_id: failed to map buffer failed to frame_map from gst_cameravpf_get_times framecount: 0 , timeunit: 33333333 pts: 0 dur: 33333333 from gst_cameravpf_fill memory[0]: is dma buffer 0:00:00.359664946 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c015c0: fd 34: mmap failed: Permission denied 0:00:00.359708540 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c015c0: subclass map failed 0:00:00.359784994 1602 0x1a82f0 ERROR default gstfdmemory.c:111:gst_fd_mem_map: 0xb5c01618: fd 35: mmap failed: Permission denied 0:00:00.359825010 1602 0x1a82f0 ERROR GST_MEMORY gstmemory.c:324:gst_memory_map: mem 0xb5c01618: subclass map failed 0:00:00.359884383 1602 0x1a82f0 ERROR default video-frame.c:155:gst_video_frame_map_id: failed to map buffer and this is my get_time code static void gst_cameravpf_get_times(GstBaseSrc *bsrc, GstBuffer *buffer, GstClockTime *start, GstClockTime *end) { g_print("from %s\n", __FUNCTION__); Gstcameravpf *src = GST_CAMERAVPF(bsrc); /* for live sources, sync on the timestamp of the buffer */ if (gst_base_src_is_live(bsrc)) { GstClockTime timeunit = gst_util_uint64_scale(1, GST_SECOND * src->videoInfo.fps_d, src->videoInfo.fps_n); std::cout << "framecount: " << src->frameCount << " , timeunit: " << timeunit << std::endl; GST_BUFFER_PTS(buffer) = src->frameCount * timeunit; GST_BUFFER_DURATION(buffer) = timeunit; std::cout << "pts: " << GST_BUFFER_PTS(buffer) << " dur: " << GST_BUFFER_DURATION(buffer) << std::endl; *end = GST_BUFFER_PTS(buffer) + GST_BUFFER_DURATION(buffer); *start = GST_BUFFER_PTS(buffer); } else { *start = -1; *end = -1; } } need i create dma buf fd for ducati? if so can you show some example code? Thanks. hi,RamPrasad Could you show me some example source element code that transfer data using dma? I implement GstPushSrc's alloc and fill function,here is the code: static GstFlowReturn gst_cameravpf_alloc(GstPushSrc *bsrc, GstBuffer **buf) { std::cout << "from " << __FUNCTION__ << std::endl; Gstcameravpf *src = GST_CAMERAVPF(bsrc); GstBuffer *buffer; GstMemory *mem; GstMapInfo info; struct dmabuf_vmem_export exp; exp.fd = -1; exp.size = src->videoInfo.size; exp.vaddr = reinterpret_cast(src->framebuffer); int ret = ioctl(src->fd, DBUFIOC_EXPORT_VIRTMEM, &exp); std::cout << "ret: " << ret << " fd: " << exp.fd << std::endl; buffer = gst_buffer_new(); GstAllocator *allocator = gst_dmabuf_allocator_new(); mem = gst_dmabuf_allocator_alloc(allocator, exp.fd, src->videoInfo.size); if (ret != 0) return GST_FLOW_ERROR; gst_buffer_append_memory(buffer, mem); *buf = buffer; return GST_FLOW_OK; } static GstFlowReturn gst_cameravpf_fill(GstPushSrc *bsrc, GstBuffer *buf) { std::cout << "from " << __FUNCTION__ << std::endl; Gstcameravpf *src = GST_CAMERAVPF(bsrc); guint64 currentTime = g_get_real_time(); guint memorynum = gst_buffer_n_memory(buf); if (gst_is_dmabuf_memory(gst_buffer_get_memory(buf, 0)) == TRUE) std::cout << "memory[0]: is dma buffer" << std::endl; #ifdef USE_CAMERA spFrame spfrm; src->cameraPtr->getnextframe(spfrm); if (!spfrm) { std::cout << "failed to get frame" << std::endl; g_usleep(10 * 1000); return GST_FLOW_OK; } memcpy(src->framebuffer, spfrm->get_addr(0), spfrm->get_datalen(0)); memcpy(src->framebuffer + src->videoInfo.height * src->videoInfo.stride[0], spfrm->get_addr(1), spfrm->get_datalen(1)); spfrm.reset(); #else memset(src->framebuffer, src->frameCount % 256, src->videoInfo.height * src->videoInfo.stride[0]); memset(src->framebuffer + src->videoInfo.height * src->videoInfo.stride[0], 0x80, src->videoInfo.height / 2 * src->videoInfo.stride[1]); #endif GstVideoFrame frame; if (!gst_video_frame_map(&frame, &src->videoInfo, buf, GST_MAP_WRITE)) { std::cout << "failed to map for dma" << std::endl; } else { gst_video_frame_unmap(&frame); } guint64 timeunit = gst_util_uint64_scale(1, GST_SECOND * src->videoInfo.fps_d, src->videoInfo.fps_n); GST_BUFFER_PTS(buf) = src->frameCount * timeunit; GST_BUFFER_DTS(buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION(buf) = timeunit; gst_object_sync_values(GST_OBJECT(bsrc), GST_BUFFER_PTS(buf)); guint64 time2sleep = (timeunit - currentTime + src->lastTime); std::cout << "time2sleep: " << time2sleep / 1000000 << "(ms) , timeunit: " << timeunit << " , frameCount: " << src->frameCount << std::endl; g_usleep(time2sleep / 1000); src->frameCount++; src->lastTime = currentTime; return GST_FLOW_OK; } but,now gstreamer still failed,here is error message: stroot@dra7xx-evm:~# gst-launch-1.0 cameravpf ! ducatih264enc ! h264parse ! qtmux ! filesink location=abc.mp4 Setting pipeline to PAUSED ... from gst_cameravpf_start Pipeline is live and does not need PREROLL ... from gst_cameravpf_setcaps caps from setcaps: video/x-raw, width=(int)1280, height=(int)720, framerate=(fraction)30/1, format=(string)NV12 get videoinfo Setting pipeline to PLAYING ... from gst_cameravpf_alloc New clock: GstSystemClock ret: 0 fd: 30 from gst_cameravpf_fill memory[0]: is dma buffer failed to map for dma time2sleep: 33(ms) , timeunit: 33333333 , frameCount: 0 MmRpc_call: Error: write failed ERROR: from element /GstPipeline:pipeline0/Gstcameravpf:cameravpf0: Internal data flow error. Additional debug info: ../../../../gstreamer-1.6.3/libs/gst/base/gstbasesrc.c(2943): gst_base_src_loop (): /GstPipeline:pipeline0/Gstcameravpf:cameravpf0: streaming task paused, reason error (-5) ../git/libdce.c:965: process ERROR: Failed eError == DCE_EOK error val -5Execution ended after 0:00:00.042136847 Setting pipeline to PAUSED ... Setting pipeline to READY ... from gst_cameravpf_stop Setting pipeline to NULL ... Freeing pipeline ... Hi,RamPrasad: Could you show me some example in which ducatih264enc works? Thanks. Hi, TI did support a software called infoadas for which is based on visionDK for video recording usecase. but that was based on visionsdk3.02 I can point you to the gstreamer plugin source code. git clone git://git.ti.com/glsdk/gstreamer1-0-plugins-bad.git cd gstreamer1-0-plugins-bad git checkout origin/infoadas_k4.4 Here ext/infoadas directory has the gstreamer plugin which is nothing but source plugin which pushes the video buffers to ducatienc. The sample pipeline will look like #H264 single channel encode as elementary stream and display the video gst-launch-1.0 infoadas chain="lvds-vip-single-cam" \ ! queue ! tee name=t ! queue ! waylandsink use-drm=true sync=false \ t. ! queue ! ducatih264enc inter-interval=1 intra-interval=60 ! queue ! filesink location=bb_single_enc1.h264 sync=false You may find some functions vivi_xxx in this plugin. This is nothing but a userspace library called libinfoadas.so to get video buffers from visionSDK's M4 to A15. I hope this helps you. Thanks RamPrasad Hi,RamPrasad: I found that TI provied CMA library. Accroding that i can alloc memory for dma buffer. In my case , i create dma buffer in my source alloc function.Here is pesudo code: GstBuffer *buffer; GstMemory *mem; GstMapInfo info; CMEM_AllocParams params; params.type = CMEM_HEAP; params.flags = CMEM_CACHED; params.alignment = 512; int poolid = CMEM_getPool(src->videoInfo.size); src->videobuffer = CMEM_allocPool(poolid, ¶ms); std::cout << "videobuffer from CMEM_alloc2: " << std::hex << src->videobuffer << std::endl; struct dmabuf_vmem_export exp; exp.fd = -1; exp.size = src->videoInfo.size; exp.vaddr = reinterpret_cast(src->videobuffer); int ret = ioctl(src->fd, DBUFIOC_EXPORT_VIRTMEM, &exp); std::cout << "ret: " << ret << " fd: " << exp.fd << std::endl; buffer = gst_buffer_new(); GstAllocator *allocator = gst_dmabuf_allocator_new(); mem = gst_dmabuf_allocator_alloc(allocator, exp.fd, src->videoInfo.size); if (ret != 0) return GST_FLOW_ERROR; gst_buffer_append_memory(buffer, mem); *buf = buffer;