工具/软件:Linux
您好、专家
我的客户报告 说、他们在 AM5728 EVM 的 PDK 03.03.00.04上发现了 ducatih264enc GStreamer 插件内存泄漏库、可以检查一下吗?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好、专家
当我与 应用程序一起使用时、会发生内存泄漏。
v4l2表示 cap 数据,v4l2 -> appsrc -> ducatih264enc (ti 表示编码)->文件链接 {这种方法是内存泄漏}
v4l2->appsrc ->文件链接{这种方法不会发现内存泄漏}
/* * * compile command arm-linux-gnueabihf-gcc app-camera.c -o app `pkg-config --cflags --libs gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0` * */ #include <linux/videodev2.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <unistd.h> #include <stdio.h> #include <stdint.h> #include <errno.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <gst/gst.h> #include <gst/app/gstappsrc.h> #define waylandsink #define v4l2src typedefstruct_App App; struct_App { GstElement *pipeline; GstElement *appsrc; GstElement *encode; GstElement *parse; GstElement *sink; GstElement *decode; GstBus *bus; GstMessage *msg; GMainLoop *loop; guint bus_watch_id; }; App s_app; intret, idx, fd; #define NBUF 3 #define FRAME_SIZE 152064 //352*288*1.5 intwidth = 352, height = 288; void*buffer_addr[NBUF]; intsize[NBUF]; staticvoid feed_data (GstElement * appsrc, guint size, App * app) { printf("feed-data....\n"); structv4l2_buffer buf; /* Dequeue one buffer */ memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if(-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { perror("Queue Buffer"); returnFALSE; } idx = buf.index; GstBuffer *buffer; GstFlowReturn ret; buffer = gst_buffer_new_allocate(NULL,FRAME_SIZE,NULL); GstMapInfo info; gst_buffer_map(buffer,&info,GST_MAP_WRITE); unsigned char* buff = info.data; memcpy(buff,buffer_addr[idx],FRAME_SIZE); gst_buffer_unmap(buffer,&info); g_signal_emit_by_name(app->appsrc,"push-buffer",buffer,&ret); printf("ret:%d\n",ret); if(ret != GST_FLOW_OK) { /* some error, stop sending data */ printf("push error...\n"); returnFALSE; } gst_buffer_unref(buffer); memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = idx; if(-1 == xioctl(fd, VIDIOC_QBUF, &buf)) { perror("Queue Buffer"); returnFALSE; } returnTRUE; } intxioctl(intfd, intrequest, void*arg) { intr; dor = ioctl (fd, request, arg); while(-1 == r && EINTR == errno); returnr; } intinit_device(intfd) { unsigned inti; structv4l2_capability caps; structv4l2_format fmt; structv4l2_requestbuffers req; structv4l2_buffer buf; /* Check for capture device */ memset(&caps, 0, sizeof(caps)); if(-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps)) { perror("Setting Pixel Format"); return1; } printf("Driver: %s\ncaps: %8x", caps.driver, caps.capabilities); if(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) { printf("Not a capture device"); return1; } /* Set capture format to UYVY */ memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; // fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; fmt.fmt.pix.field = V4L2_FIELD_NONE; if(-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) { perror("Setting Pixel Format"); return1; } printf("Selected Camera Mode:\n"" Width: %d\n"" Height: %d\n"" Field: %d", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.field); printf(" PixFmt = %c%c%c%c\n", fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF, (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) &0xFF); /* Currently driver supports only mmap buffers * Request memory mapped buffers */ memset(&req, 0, sizeof(req)); req.count = NBUF; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if(-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { perror("Requesting Buffer"); return1; } printf("Total buffer num %d\n", req.count); for(i = 0; i < req.count; i++) { memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) { perror("Querying Buffer"); return1; } /* Memory map all the buffers and save the addresses */ buffer_addr[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); //buffer_addr[i]=(void*)malloc(FRAME_SIZE); size[i] = buf.length; printf("Address %p, size %d, image size: %d \n", buffer_addr[i], buf.length, buf.bytesused); /* Queue the buffer for capture */ memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if(-1 == xioctl(fd, VIDIOC_QBUF, &buf)) { perror("Queue Buffer"); return1; } printf("12345\r\n"); } if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type)) { perror("Start Capture"); return1; } return0; } voidrelease_device(intfd) { inttype = V4L2_BUF_TYPE_VIDEO_CAPTURE; xioctl(fd, VIDIOC_STREAMOFF, &type); close(fd); } gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch(GST_MESSAGE_TYPE (msg)) { caseGST_MESSAGE_EOS: fprintf(stderr, "End of stream\n"); g_main_loop_quit(loop); break; caseGST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error(msg, &error, &debug); g_free(debug); g_printerr("Error: %s\n", error->message); g_error_free(error); g_main_loop_quit(loop); break; } default: break; } returnTRUE; } intmain(intargc, char**argv) { App *app = &s_app; printf("==========\n"); chardevnode[100] = "/dev/video1"; fd = open(devnode, O_RDWR); if(fd == -1) { perror("Opening video device"); return1; } ret = init_device(fd); if(0 != ret) { printf("Exiting"); returnret; } gst_init(NULL,NULL); app->pipeline = gst_pipeline_new("encodepipeline"); g_assert(app->pipeline); app->appsrc = gst_element_factory_make("appsrc","srcElement"); g_assert(app->appsrc); app->encode = gst_element_factory_make("ducatih264enc","encodeElement"); g_assert(app->encode); app->parse = gst_element_factory_make("h264parse","parseElement"); g_assert(app->parse); app->decode = gst_element_factory_make("ducatih264dec","decodeElement"); g_assert(app->decode); app->sink = gst_element_factory_make("filesink","sinkElement"); g_assert(app->sink); printf("element creat success\n"); GstCaps *capsappsrc2H264enc; capsappsrc2H264enc = gst_caps_new_simple("video/x-raw", "format",G_TYPE_STRING, "NV12", "width", G_TYPE_INT, 352, "height",G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 30, 1, NULL); // g_object_set(G_OBJECT (app->sink), "sync", FALSE, // NULL); gst_app_src_set_caps(GST_APP_SRC(app->appsrc), capsappsrc2H264enc); g_object_set(app->sink,"location","/mnt/camera.yuv",NULL); app->loop = g_main_loop_new(NULL,FALSE); app->bus = gst_pipeline_get_bus(GST_PIPELINE(app->pipeline)); app->bus_watch_id = gst_bus_add_watch(app->bus,bus_call,app->loop); gst_object_unref(app->bus); gst_bin_add_many(GST_BIN(app->pipeline), app->appsrc,app->sink,NULL); gboolean bLinkOk; bLinkOk= gst_element_link(app->appsrc,app->sink); if(!bLinkOk){ g_warning("Failed to link many 1\n"); return-5; } g_signal_connect(app->appsrc, "need-data", G_CALLBACK(feed_data), app); gst_element_set_state (app->pipeline, GST_STATE_PLAYING); printf("run....1\n"); g_main_loop_run(app->loop); printf("run....2\n"); app->msg = gst_bus_timed_pop_filtered (app->bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); if(app->msg != NULL) gst_message_unref (app->msg); gst_object_unref (app->bus); gst_element_set_state (app->pipeline, GST_STATE_NULL); gst_object_unref (app->pipeline); gst_object_unref(app->appsrc); gst_object_unref(app->sink); printf("close...\n"); return0; }我尚未使用 ducatimpeg4enc、有关 ducatih264enc、您可以查看此页面 e2e.ti.com/.../2287603
我只使用 TOP 命令来检测内存泄漏。
您好!
[引用用户="abayyyyyyyy"]谢谢、但我不知道如何仅使用 ti-processor-sdk-linux-am57xx-evm-03.03.00.04 SDK 构建 ducatih264enc 插件?
该问题并非仅针对 ducatih264enc。
这是 PSDK 版本03.03.00.04的用户指南
processors.wiki.ti.com/index.php
请按照指南中的步骤操作。
这是构建 Ducati 插件的最后一步:
MACHINE=am57xx-EVM bitbake gstreamer1.0-plugins-Ducati
您可以在 gstducatividenc.c 文件中手动应用修补程序。
请查看指南中的强制重新编译章节。
新的 libgstducati.so 文件应为 cp 到 rootfs//usr/lib/gstreamer-1.0。
希望这对您有所帮助。
BR
玛格丽塔
您好!
检查附件:
e2e.ti.com/.../libgstducati.zip
BR
玛格丽塔
您好、Margarita:
客户的测试方案如下:
gst-launch-1.0 -v -e v4l2src device=/dev/video1 io-mode=2! 'video/x-raw、format=(string) NV12、width=(int) 800、height=(int) 600、framerate=(fraction) 30/1、bitrate=(int) 30'! ducatih264enc! h264parse! ducatih264dec! landwaysink 同步=错误
那么、您可以重现此问题吗? 是否可以在解决内存泄漏问题后提供更新的插件? 谢谢
尊敬的 Jian:
我在您的流水线中再现了该问题。 我分析了 ducatiDecoder 源代码,发现每帧有一个小内存泄漏,但修复此泄漏后,仍然观察到顶部命令中的 Mem%增加。
我已附上修改后的 libgstducati.so 用于您的测试。 您能确认该行为吗?
另一个观察结果是、如果管线中的 kmsink 被 fakesink 替换、则没有记忆泄漏。
kmsink 或 waylandsink 出现问题。
e2e.ti.com/.../6012.libgstducati.zip
RAM