Gstreamer自定义插件从文件读取数据(YUV)?

时间:2015-10-14 09:40:30

标签: linux video gstreamer video-processing multimedia

好的,让我先解释一下为什么我需要一个自定义过滤器来读取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

但它正在显示这样的视频

gst-launch not showing video

任何人都可以帮我找到我的错误吗?我对gstreamer很新。

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

1 个答案:

答案 0 :(得分: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

这给了我以下输出

gst video

可以在此myfilesrc.zip文件中找到该代码。这段代码不应该整洁干净。但是工程师可以很容易地理解它。