在玩了一些玩具应用程序后,探索 文档和谷歌搜索(包括邮件列表 档案)我仍然感到困惑,我认为这是一个相当普遍的 用例。
我有一个现有的代码生成图像(在内存中),我会 喜欢将这些图像推入gstreamer管道(创建一个flv 最后的视频)。
我找不到“显而易见的方法”。我最好的猜测是 挖掘GstMultiFileSrc的源代码及其父GstPushSrc, 弄明白。
你们有没有人指出我这样做的“显而易见的方式”? 是否有任何相关的文档/教程/示例?
一旦我输入正确,剩下的就是小菜一碟,谢谢 Gstreamer太棒了! (类似于“我的魔法输入 - > ffmpegcolorspace!ffenc_flv! flvmux! filesink location = desktop.flv“)
感谢您的回答。
答案 0 :(得分:7)
GStreamer使用插件来完成所有事情。创建数据或从外部源获取数据的插件称为“src”插件。
用于将应用程序生成的数据注入管道的通用src插件称为appsrc。 appsrc提供的API记录为App Library。
的一部分这是一个示例,演示了如何使用生成的图像提供apprc:gdk-gstappsrc-stream.c。它似乎源自GStreamer源代码树中的一些测试代码:here。
另一种方法是创建自己的src插件。查看goom音乐可视化插件,查看一个似乎与您指定的方式类似的示例。
答案 1 :(得分:2)
我找到了一个解决方案(也许)(我用OpenCV获取图像)...但是管道出错了:来自元素mysource的错误:错误en el flujo de datos interno。 调试信息:gstbasesrc.c(2574):gst_base_src_loop():/ GstPipeline:pipeline0 / GstAppSrc:mysource: 流媒体任务暂停,原因未协商(-4)
这是代码:
typedef struct _App App;
struct _App{
GstElement *pipeline;
GstElement *appsrc;
GMainLoop *loop;
guint sourceid;
GTimer *timer;
};
App s_app;
CvCapture *capture;
static gboolean read_data(App *app){
GstFlowReturn ret;
GstBuffer *buffer = gst_buffer_new();
IplImage* frame = cvQueryFrame(capture);
GST_BUFFER_DATA(buffer) = (uchar*)frame->imageData;
GST_BUFFER_SIZE(buffer) = frame->width*frame->height*sizeof(uchar*);
g_signal_emit_by_name(app->appsrc,"push-buffer",buffer,&ret);
gst_buffer_unref(buffer);
if(ret != GST_FLOW_OK){
GST_DEBUG("Error al alimentar buffer");
return FALSE;
}
return TRUE;
}
static void start_feed(GstElement* pipeline,guint size, App* app){
if(app->sourceid == 0){
GST_DEBUG("Alimentando");
app->sourceid = g_idle_add((GSourceFunc) read_data, app);
}
}
static void stop_feed(GstElement* pipeline, App* app){
if(app->sourceid !=0 ){
GST_DEBUG("Stop feeding");
g_source_remove(app->sourceid);
app->sourceid = 0;
}
}
static gboolean
bus_message (GstBus * bus, GstMessage * message, App * app)
{
GST_DEBUG ("got message %s",
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR: {
GError *err = NULL;
gchar *dbg_info = NULL;
gst_message_parse_error (message, &err, &dbg_info);
g_printerr ("ERROR from element %s: %s\n",
GST_OBJECT_NAME (message->src), err->message);
g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
g_error_free (err);
g_free (dbg_info);
g_main_loop_quit (app->loop);
break;
}
case GST_MESSAGE_EOS:
g_main_loop_quit (app->loop);
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[]){
App *app = &s_app;
GError *error = NULL;
GstBus *bus;
GstCaps *caps;
capture = cvCaptureFromCAM(0);
gst_init(&argc,&argv);
/* create a mainloop to get messages and to handle the idle handler that will
* feed data to appsrc. */
app->loop = g_main_loop_new (NULL, TRUE);
app->timer = g_timer_new();
app->pipeline = gst_parse_launch("appsrc name=mysource ! video/x-raw-rgb,width=640,height=480,bpp=24,depth=24 ! ffmpegcolorspace ! videoscale method=1 ! theoraenc bitrate=150 ! tcpserversink host=127.0.0.1 port=5000", NULL);
g_assert (app->pipeline);
bus = gst_pipeline_get_bus (GST_PIPELINE (app->pipeline));
g_assert(bus);
/* add watch for messages */
gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);
/* get the appsrc */
app->appsrc = gst_bin_get_by_name (GST_BIN(app->pipeline), "mysource");
g_assert(app->appsrc);
g_assert(GST_IS_APP_SRC(app->appsrc));
g_signal_connect (app->appsrc, "need-data", G_CALLBACK (start_feed), app);
g_signal_connect (app->appsrc, "enough-data", G_CALLBACK (stop_feed), app);
/* set the caps on the source */
caps = gst_caps_new_simple ("video/x-raw-rgb",
"bpp",G_TYPE_INT,24,
"depth",G_TYPE_INT,24,
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
gst_app_src_set_caps(GST_APP_SRC(app->appsrc), caps);
/* go to playing and wait in a mainloop. */
gst_element_set_state (app->pipeline, GST_STATE_PLAYING);
/* this mainloop is stopped when we receive an error or EOS */
g_main_loop_run (app->loop);
GST_DEBUG ("stopping");
gst_element_set_state (app->pipeline, GST_STATE_NULL);
gst_object_unref (bus);
g_main_loop_unref (app->loop);
cvReleaseCapture(&capture);
return 0;
}
任何想法???
答案 2 :(得分:1)
您可以尝试黑客imagefreeze来做你想做的事。 appsrc也可能会这样做。