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

猜你喜欢

转载自blog.csdn.net/qq_23350817/article/details/103601993