好的,让我先解释一下为什么我需要一个自定义过滤器来读取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作为我的驱动源,因为我的自定义插件尚未编码为独立工作。
答案 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
这给了我以下输出
可以在此myfilesrc.zip文件中找到该代码。这段代码不应该整洁干净。但是工程师可以很容易地理解它。