上一篇文章中,提供了发送视频帧数据的方法。有人问了,这是理想情况,对于编码数据,怎么办?
经过一番折腾,终于找到可用的办法。下面代码,测试通过:
#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; }