gstreamer向appsrc发送编码数据的代码

经过一番折腾,终于找到可用的办法。下面代码,测试通过:

#include <gst/gst.h>
 
static FILE * appSrcFile = NULL;
static int  read_counter = 0;
static char read_buffer[4096];
 
static void cb_need_data (GstElement *source, guint       unused_size, gpointer    user_data)
{
    GstBuffer *buffer;
    GstFlowReturn ret;
    GstMapInfo map;
 
    g_print("%s\n", __func__);
 
    if (appSrcFile == NULL)
    {
       appSrcFile = fopen("sample_720p.h264", "r");
    }
 
    size = fread(read_buffer, 1, size, appSrcFile);
    g_print("read_data() read_counter=%d, size=%d\n", read_counter++, size);
 
    if(size == 0)
    {
        ret = gst_app_src_end_of_stream(source);
        g_print("eos returned %d at %d\n", ret, __LINE__);
        return;
    }
 
    buffer = gst_buffer_new_allocate (NULL, size, NULL);
//这两个方法都可以
#if 0
    gst_buffer_fill(buffer, 0, read_buffer, size);
#else
    gst_buffer_map (buffer, &map, GST_MAP_WRITE);
    memcpy( (guchar *)map.data, read_buffer, gst_buffer_get_size( buffer ) );
#endif
 
    g_signal_emit_by_name (source, "push-buffer", buffer, &ret);
    gst_buffer_unref (buffer);
}
 
 
gint main (gint   argc, gchar *argv[])
{
  GstElement *pipeline, *appsrc, *conv, *videosink;
 
  /* init GStreamer */
  gst_init (NULL, NULL);
  GMainLoop* loop = g_main_loop_new (NULL, FALSE);
 
  /* setup pipeline */
  pipeline  = gst_pipeline_new ("pipeline");
  appsrc    = gst_element_factory_make ("appsrc",       "source");
  conv      = gst_element_factory_make ("videoconvert", "conv");
  videosink = gst_element_factory_make ("xvimagesink",  "videosink");
 
  gst_bin_add_many (GST_BIN (pipeline), appsrc, conv, videosink, NULL);
  gst_element_link_many (appsrc, conv, videosink, NULL);
 
 //AppSrc可以工作在俩种模式下:Pull模式和Push模式。Pull模式下,AppSrc会在需要的时候向应用
 //程序请求数据(信号:need-data),而Push模式下,应用程序主动向AppSrc注入数据(信号:enough-data)。此时会触发回调函数的执行,然后在回调函数里面解析视屏文件然后播放出来。
  /* setup appsrc */
  g_signal_connect (appsrc, "need-data",   G_CALLBACK (cb_need_data), NULL);
  g_object_set(     appsrc, "stream-type", GST_APP_STREAM_TYPE_STREAM, NULL );
 
  /* play */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);
 
  /* clean up */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));
  g_main_loop_unref (loop);
 
  return 0;
  }
在C语言中使用GStreamer将图像数据编码为JPEG格式的步骤如下: 1. 导入必要的头文件和库文件: ```c #include <gst/gst.h> #include <stdio.h> /* 编译时需要使用`pkg-config --cflags --libs gstreamer-1.0`命令获取相应的编译选项 */ ``` 2. 创建GStreamer管道: ```c GstElement *pipeline; pipeline = gst_pipeline_new("image-pipeline"); ``` 3. 创建GStreamer元素: ```c GstElement *jpegenc, *appsink; jpegenc = gst_element_factory_make("jpegenc", "jpeg-encoder"); appsink = gst_element_factory_make("appsink", "app-sink"); ``` 4. 设置元素属性: ```c g_object_set(G_OBJECT(jpegenc), "quality", 80, NULL); ``` 5. 将元素添加到管道中: ```c gst_bin_add_many(GST_BIN(pipeline), appsink, jpegenc, NULL); ``` 6. 设置管道状态为“播放”: ```c gst_element_set_state(pipeline, GST_STATE_PLAYING); ``` 7. 将图像数据传递给元素: ```c GstBuffer *buffer; // 假设img_data为图像数据,img_size为图像数据的大小 buffer = gst_buffer_new_allocate(NULL, img_size, NULL); gst_buffer_fill(buffer, 0, img_data, img_size); g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, "sync", FALSE, NULL); g_signal_connect(appsink, "new-sample", G_CALLBACK(on_new_sample), buffer); ``` 8. 定义新样本回调函数: ```c GstFlowReturn on_new_sample(GstElement *sink, gpointer data) { GstSample *sample; GstBuffer *buffer; GstMapInfo map; buffer = (GstBuffer *)data; sample = gst_sample_new(buffer, NULL, NULL, NULL); gst_buffer_map(buffer, &map, GST_MAP_READ); // 将JPEG数据写入文件中 FILE *fp = fopen("image.jpg", "wb"); fwrite(map.data, map.size, 1, fp); fclose(fp); gst_buffer_unmap(buffer, &map); gst_sample_unref(sample); return GST_FLOW_OK; } ``` 9. 释放资源: ```c gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); ``` 完整的代码如下: ```c #include <gst/gst.h> #include <stdio.h> GstFlowReturn on_new_sample(GstElement *sink, gpointer data); int main(int argc, char *argv[]) { GstElement *pipeline, *jpegenc, *appsink; GstBuffer *buffer; GstMapInfo map; guint8 *img_data; // 图像数据 guint img_size; // 图像数据大小 /* 初始化GStreamer */ gst_init(&argc, &argv); /* 创建GStreamer管道 */ pipeline = gst_pipeline_new("image-pipeline"); /* 创建GStreamer元素 */ jpegenc = gst_element_factory_make("jpegenc", "jpeg-encoder"); appsink = gst_element_factory_make("appsink", "app-sink"); /* 设置元素属性 */ g_object_set(G_OBJECT(jpegenc), "quality", 80, NULL); /* 将元素添加到管道中 */ gst_bin_add_many(GST_BIN(pipeline), appsink, jpegenc, NULL); /* 将管道设置为“播放”状态 */ gst_element_set_state(pipeline, GST_STATE_PLAYING); /* 将图像数据传递给元素 */ buffer = gst_buffer_new_allocate(NULL, img_size, NULL); gst_buffer_fill(buffer, 0, img_data, img_size); g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, "sync", FALSE, NULL); g_signal_connect(appsink, "new-sample", G_CALLBACK(on_new_sample), buffer); /* 等待图像编码完成 */ getchar(); /* 释放资源 */ gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); return 0; } GstFlowReturn on_new_sample(GstElement *sink, gpointer data) { GstSample *sample; GstBuffer *buffer; GstMapInfo map; buffer = (GstBuffer *)data; sample = gst_sample_new(buffer, NULL, NULL, NULL); gst_buffer_map(buffer, &map, GST_MAP_READ); /* 将JPEG数据写入文件中 */ FILE *fp = fopen("image.jpg", "wb"); fwrite(map.data, map.size, 1, fp); fclose(fp); gst_buffer_unmap(buffer, &map); gst_sample_unref(sample); return GST_FLOW_OK; } ``` 其中,img_data和img_size需要根据实际的图像数据进行设置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值