上一篇文章中,提供了發送視訊幀資料的方法。有人問了,這是理想情況,對于編碼資料,怎麼辦?
經過一番折騰,終于找到可用的辦法。下面代碼,測試通過:
#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);
/* 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;
}