gstreamer基于appsink实现截图

对gstreamer官方教程中的基于appsink的视频帧采样代码进行了重新封装,以达到通过GTK的button事件直接调用封装进行视频截图。注意设置好主pipeline中的节点tee与封装中的tee_main进行同步。参考代码如下:appdata.mediaData.tee_main = data.tee_main;

https://thiblahute.github.io/GStreamer-doc/application-development/advanced/pipeline-manipulation.html?gi-language=c#appsink-example

typedef struct _MediaData
{
    GstElement *pipeline;
    GstElement *tee_main ;
    GstElement *capsfilter_cap, *videoconvert_cap, *capture_queue,*file_sink_capture;
    GstCaps *filter_caps_cap;
    GstPad *queue_capture_pad, *tee_capture_pad;
} MediaData;

typedef struct _AppData
{
    GstElement *pipeline_app;
    GstElement *video_sink;
    MediaData  mediaData;
} AppData;

static int image_cap_cb (GtkEventBox *e, CustomData * data)
{
    static int screenshot_time = 1;
    GstSample *sample;
    MediaData*  imageData = &appdata.mediaData;
    GstPadTemplate *templ;
    templ = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (imageData->tee_main), "src_%u");
    imageData->tee_capture_pad   = gst_element_request_pad  (imageData->tee_main, templ, NULL, NULL);
    if ( 1 )
    {
        imageData->capture_queue     = gst_element_factory_make ("queue", "record_queue");
        imageData->videoconvert_cap  = gst_element_factory_make ("videoconvert", "videoconvert_cap");
        imageData->capsfilter_cap = gst_element_factory_make ("capsfilter", "capsfilter_cap");
        imageData->file_sink_capture = gst_element_factory_make ("appsink", "file_sink_capture");
        g_object_set (imageData->file_sink_capture, "emit-signals", TRUE, NULL);

        /* set the resolution */
        char resolution_cap[200];
        sprintf(resolution_cap, "video/x-raw,format=RGBA, pixel-aspect-ratio=1/1");
        g_printerr("%s\n",resolution_cap);
        imageData->filter_caps_cap   = gst_caps_from_string (resolution_cap);
        g_object_set(GST_OBJECT( imageData->capsfilter_cap), "caps",  imageData->filter_caps_cap, NULL);
        gst_caps_unref ( imageData->filter_caps_cap);
        char  filename_png[1000];
        sprintf(filename_png, "/home/123/screeshot%d.jpg", screenshot_time);
        screenshot_time++;
        gst_bin_add_many (GST_BIN (imageData->pipeline), imageData->capture_queue,imageData->videoconvert_cap, imageData->capsfilter_cap, imageData->file_sink_capture,NULL);
        if (gst_element_link_many (imageData->capture_queue,  imageData->videoconvert_cap,   imageData->capsfilter_cap, imageData->file_sink_capture, NULL) != TRUE)
        {
            g_printerr ("Elements could not be linked in record branch\n");
        }
        gst_element_sync_state_with_parent (imageData->capture_queue);
        gst_element_sync_state_with_parent (imageData->videoconvert_cap);
        gst_element_sync_state_with_parent (imageData->capsfilter_cap);
        gst_element_sync_state_with_parent (imageData->file_sink_capture);
        imageData->queue_capture_pad = gst_element_get_static_pad (imageData->capture_queue, "sink");
        if(gst_pad_link (imageData->tee_capture_pad,  imageData->queue_capture_pad) != GST_PAD_LINK_OK)
        {
            g_printerr ("Elements could not be linked in record branch\n");
        }
        if (sample)
        {
            GstBuffer *buffer;
            GstPad *pad;
            GstStructure *s;
            gint width, height;
            GstPadTemplate *template;
            g_signal_emit_by_name (imageData->file_sink_capture, "pull-preroll", &sample, NULL);
            GstCaps *videosink_caps = gst_sample_get_caps (sample);
            s = gst_caps_get_structure (videosink_caps, 0);
            gboolean res;
            res = gst_structure_get_int (s, "width", &width);
            res |= gst_structure_get_int (s, "height", &height);
            GstMapInfo map;
            GError *error = NULL;
            buffer = gst_sample_get_buffer (sample);
            gst_buffer_map (buffer, &map, GST_MAP_READ);
            g_printerr("width :%d, height :%d \n", width, height);
            pixbuf = gdk_pixbuf_new_from_data (map.data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, GST_ROUND_UP_4 (width*4), NULL, NULL);
            gdk_pixbuf_save (pixbuf, filename_png, "jpeg", &error,NULL);
            gst_buffer_unmap (buffer, &map);
        }
        usleep(100*1000);
        gst_element_set_state (imageData->file_sink_capture, GST_STATE_NULL);
        gst_element_set_state (imageData->videoconvert_cap, GST_STATE_NULL);
        gst_element_set_state (imageData->capture_queue, GST_STATE_NULL);
        gst_element_set_state (imageData->capsfilter_cap, GST_STATE_NULL);
        imageData->queue_capture_pad = gst_element_get_static_pad (imageData->capture_queue, "sink");
        if(gst_pad_unlink(imageData->tee_capture_pad, imageData->queue_capture_pad) != TRUE)
        {
            g_printerr ("Tee record queue could not be unlinked.\n");
        }
        gst_bin_remove(GST_BIN (imageData->pipeline), imageData->capture_queue);
        gst_bin_remove(GST_BIN (imageData->pipeline), imageData->videoconvert_cap);
        gst_bin_remove(GST_BIN (imageData->pipeline), imageData->file_sink_capture);
        gst_bin_remove(GST_BIN (imageData->pipeline), imageData->capsfilter_cap);
        gst_element_release_request_pad (imageData->tee_main, imageData->tee_capture_pad);
        gst_object_unref (imageData->queue_capture_pad);
        gst_object_unref (imageData->tee_capture_pad);
        g_printerr("TRUE \n");
    }
    return 1;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值