2011-03-15 43 views
6

一些玩具应用玩耍,探索 文档和谷歌搜索周围(包括邮件列表 档案)我仍然疑惑什么,我会认为这是一个相当常见的 使用情况后。推图像成GStreamer的管道

我有一个现有的代码生成图像(在存储器中),我会 喜欢这些图像推入一个gstreamer的管道(以创建在末端具有FLV 视频)。

我找不到一个“明显的做法”。我最好的猜测是 挖掘GstMultiFileSrc的源代码和它的父GstPushSrc, 找出来。

难道你们中的任何人都可以指出我这样做的“明显方式”吗? 这里有没有相关的文档/教程/例子?

一旦我有了正确的输入,剩下的就是小菜一碟,感谢 Gstreamer真棒! (像 “我的魔法输入! - > ffmpegcolorspace ffenc_flv flvmux文件接收地点= desktop.flv!”)

谢谢您的回答。

回答

7

GStreamer使用插件来完成一切。创建数据或从外部源获取数据的插件称为“src”插件。

用于将应用程序生成的数据注入流水线的通用src插件被称为appsrc。 appsrc提供的API记录为App Library的一部分。

下面是一个演示如何使用生成的图像提供appsrc的示例:gdk-gstappsrc-stream.c。它似乎来源于GStreamer源代码树中的一些测试代码:here

另一种方法是创建自己的src插件。看一下goom音乐可视化插件,看起来它的工作方式与您指定的方式类似。

+0

谢谢! GstAppSrc正是我正在寻找的。 – rodrigob 2011-03-15 18:23:38

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; 
} 

任何想法???

+0

尝试将此作为单独问题发布,而不是回答 – 2011-04-01 08:30:39