【问题标题】:Gstreamer custom plugin to read data (YUV) from file?Gstreamer 自定义插件从文件中读取数据(YUV)?
【发布时间】:2015-10-14 09:40:30
【问题描述】:

好的,让我先解释一下为什么我需要自定义过滤器来读取 yuv 文件或缓冲区。

我们正在开发一个相机接口,它的驱动程序不兼容 V4L2。所以我们对其进行了调整,并从中得到了一个 YUV 格式的帧。目前我必须使用我的自定义 gstreamer 插件访问该框架。

所以为了概念验证,我试图从 YUV 文件中读取数据并尝试显示它。

1)我将.mp4文件转换为.yuv格式如下

ffmpeg -i input.mp4 -f rawvideo -vcodec rawvideo -pix_fmt yuv420p -s 640x480 -r 30 rawvideo.yuv

2) 我使用 gstreamer 管道成功播放了 yuv 文件,如下所示

gst-launch-1.0 filesrc location=rawvideo.yuv ! videoparse width=640 height=480 framerate=30/1 ! autovideoconvert ! autovideosink

3) 我制作了一个自定义插件,将其命名为 myfilter 并使用以下代码对其进行调整以从 yuv 文件中读取

FILE *V_fp = NULL;

GstBuffer * read_from_videofile(void)
{

   GstBuffer *filedata;

   if(V_fp == NULL)
   {
       V_fp = fopen("/home/linux/rawvideo.yuv","rb");
   }

   //file open
   if(NULL != V_fp)
   {
       //Get Size of Data
       int size = 24;

       //allocate memory
       filedata = gst_buffer_new_allocate(NULL,size,NULL);

       //clear memory
       gst_buffer_memset(filedata, 0, '\0', size);

       //fill data into the buffer
       if(size != gst_buffer_fill(filedata, 0,V_fp,size))
       {
           fclose(V_fp);
           return NULL;
       }

   }

   return filedata;
}

/* chain function
 * this function does the actual processing
 */
static GstFlowReturn
gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstMyFilter *filter;

  filter = GST_MYFILTER (parent);

  GstFlowReturn ret = GST_FLOW_ERROR;

  if (filter->silent == FALSE)
      g_print ("I'm plugged, therefore I'm in.\n");


  GstBuffer *data = read_from_videofile();

  if(NULL != data)
  {
      /* just push out the incoming buffer without touching it */
      //return gst_pad_push (filter->srcpad, buf);
      ret = gst_pad_push (filter->srcpad,data);
      if(GST_FLOW_OK == ret)
          g_print("Data pushed successfully\n");
      else
          g_print("Error in pushing Data\n");
  }
  else
  {
      g_print("Data read failed\n");
  }

  return ret;
}

在此之后我将我的插件添加到 gstreamer 管道

gst-launch-1.0 fakesrc ! myfilter ! videoparse width=640 height=480 framerate=30/1 ! autovideoconvert ! autovideosink

但它正在显示这样的视频

谁能帮我找出我的错误?我是 gstreamer 的新手。

注意:- 我使用 fakesrc 作为我的驱动源,因为我的自定义插件尚未编码为独立工作。

【问题讨论】:

  • 我很确定你不想将你的 FILE 指针传递给gst_buffer_fill,如果你想使用那个方法,你需要先将它读入内存。
  • @mpr,你能详细说明我应该怎么做吗?因为正如你所建议的,我用我的 FILE 指针填充了一个内存,然后将它复制到 gstbuffer。但是还是不行。
  • 你会想要阅读像 freadmmap 这样的函数。 FILE 指针是指向打开文件描述符的指针,而不是文件中的数据。
  • @mrp,我按照你的建议在 O_RDWR 模式下打开文件,使用 mmap 和读取函数将文件数据映射到内存中,然后将此内存复制到 gstbuffer。现在它显示一个“黑色”屏幕。那我还能做些什么吗? Guyz 请帮助我在这一点上陷入困​​境。
  • 根据我的理解,@mrp 的含义是(在已经创建的 GstBuffer 上逐步执行此操作)1)GstMapInfo 信息; 2) gst_buffer_map (buf, &info, GST_MAP_WRITE); 3) fread(info.data,1,size,V_fp); 4) gst_buffer_unmap (buf, &info);

标签: linux video gstreamer video-processing multimedia


【解决方案1】:

按如下方式完成。

GstBuffer * read_from_videofile(void)
{

   GstBuffer *filedata;

   if(V_fp == NULL)
   {   
       V_fp = fopen(READ_LOCATION_VIDEO,"rb");
   }   

   if(NULL != V_fp)
   {   
       //Add this IF contition to play video continuously in loop
       if(feof(V_fp))
       {
           fseek(V_fp,0,SEEK_SET);
       }

       int size = 307200;// (640 * 480)
       void *data = (void *) malloc(size * sizeof(void));

       size = fread(data,1,size,V_fp);

       //Creates a new buffer that wraps the given data . The memory will be freed with g_free and will be marked writable.
       filedata = gst_buffer_new_wrapped(data,size);

       //free(data);
   }

   return filedata;
}

之后我在终端上运行了以下命令

gst-launch-1.0 fakesrc ! myfilter ! videoparse width=640 height=480 framerate=30/1 ! autovideoconvert ! autovideosink

这给了我以下输出

代码可以在这个myfilesrc.zip 文件中找到。这段代码并不像应有的那样整洁。但是工程师可以很容易地理解它。

【讨论】:

  • 我会尽量让这个插件独立于“fakesrc”并发布整个代码。
  • 当然~,那会很有帮助。
  • @fizzbuzz 将在一天内上传。并更新答案。
  • @fizzbuzz 找到附加的代码。如果您有任何其他问题,请随时提出。
  • 尽快看看,谢谢
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
相关资源
最近更新 更多