⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playback.c

📁 本程序使用gstreamer实现音视频播放,。
💻 C
📖 第 1 页 / 共 3 页
字号:
//////////////////////////////////////////////////////////////////////descriptor: this is streaming media playback function, which is support audio //			and video process by gstreamer.////////////////////////////////////////////////////////////////////#include "playback.h"GstAudioVideo media;//////////////////////////////////////////////////////////////////////////////////////for gstreamer playback./////////////////////////////////////////////////////descriptor: //para://return value://////////////////////////////////////////////////void gst_local_init(){  printf("	++++ %s ++++\n", __func__);  media.stream_length = 0;  media.play_state = GST_PLAY;  media.g_pipe = NULL;  media.speakersetup = AUDIO_SOUND_STEREO;  media.lock = g_mutex_new();  }/////////////////////////////////////////////////////descriptor: search colorbalance element.//para: fold function to pick the best colorspace element //return value://////////////////////////////////////////////////static gboolean find_colorbalance_element (GstElement *element, GValue * ret, GstElement **cb){  printf("	++++ %s ++++\n", __func__);  GstColorBalanceClass *cb_class;  g_print ("Checking element %s ...", GST_OBJECT_NAME (element));  if (!GST_IS_COLOR_BALANCE (element))    return TRUE;  g_print ("Element %s is a color balance", GST_OBJECT_NAME (element));  cb_class = GST_COLOR_BALANCE_GET_CLASS (element);  if (GST_COLOR_BALANCE_TYPE (cb_class) == GST_COLOR_BALANCE_HARDWARE)   {    gst_object_replace ((GstObject **) cb, (GstObject *) element);    /* shortcuts the fold */    return FALSE;  }   else if (*cb == NULL)   {    gst_object_replace ((GstObject **) cb, (GstObject *) element);    return TRUE;  } else {    return TRUE;  }}/////////////////////////////////////////////////////descriptor: update video interface.//para:  //return value://////////////////////////////////////////////////static void update_interface(){  GstColorBalance *old_balance = media.balance;  GstXOverlay *old_xoverlay = media.xoverlay;  GstElement *video_sink = NULL;  GstElement *element = NULL;  GstIteratorResult ires;  GstIterator *iter;  guint i;  //g_object_get (media.videosink, "sink", &video_sink, NULL);  //g_assert (video_sink != NULL);  /* We try to get an element supporting XOverlay interface */  if (GST_IS_BIN (media.videosink))   {    GST_DEBUG ("Retrieving xoverlay from bin ...");    element = gst_bin_get_by_interface (GST_BIN (media.videosink),                                        GST_TYPE_X_OVERLAY);  }  else   {    element = media.videosink;  }  if (GST_IS_X_OVERLAY (element))   {    g_print ("Found xoverlay: %s\n", GST_OBJECT_NAME (element));    media.xoverlay = GST_X_OVERLAY (element);  }   else   {    g_print ("No xoverlay found\n");    media.xoverlay = NULL;  }  /* Find best color balance element (using custom iterator so   * we can prefer hardware implementations to software ones) */  /* FIXME: this doesn't work reliably yet, most of the time   * the fold function doesn't even get called, while sometimes   * it does ... */  iter = gst_bin_iterate_all_by_interface (GST_BIN (media.g_pipe),                                           GST_TYPE_COLOR_BALANCE);  /* naively assume no resync */  element = NULL;  ires = gst_iterator_fold (iter,      (GstIteratorFoldFunction) find_colorbalance_element, NULL, &element);  gst_iterator_free (iter);  if (element)   {    media.balance = GST_COLOR_BALANCE (element);    g_print ("Best colorbalance found: %s",        GST_OBJECT_NAME (media.balance));  }   else if (GST_IS_COLOR_BALANCE (media.xoverlay))   {    media.balance = GST_COLOR_BALANCE (media.xoverlay);    gst_object_ref (media.balance);    g_print ("Colorbalance backup found: %s",        GST_OBJECT_NAME (media.balance));  }   else   {    g_print ("No colorbalance found\n");    media.balance = NULL;  }  /* Setup brightness and contrast */  //for (i = 0; i < G_N_ELEMENTS (video_props_str); i++) {  //  confvalue = gconf_client_get_without_default (bvw->priv->gc,  //      video_props_str[i], NULL);  //  if (confvalue != NULL) {  //    bacon_video_widget_set_video_property (bvw, i,  //      gconf_value_get_int (confvalue));  //    gconf_value_free (confvalue);  //  }  //}  if (old_xoverlay)    gst_object_unref (GST_OBJECT (old_xoverlay));  if (old_balance)    gst_object_unref (GST_OBJECT (old_balance));  gst_object_unref (video_sink);}//#endif/////////////////////////////////////////////////////descriptor: create video pad//para://return value://////////////////////////////////////////////////static voidgot_new_video_sink_bin_element (GstBin *video_sink, GstElement *element,                                gpointer data){  printf("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n");  //BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (data);  g_mutex_lock (media.lock);  update_interface ();  g_mutex_unlock (media.lock);}/////////////////////////////////////////////////////descriptor: create video pad//para://return value://////////////////////////////////////////////////static GstElement *video_create(){  GstElement *element;  GstElement *conv;  GstElement *sink;  GstPad *pad;  printf("	++++ %s ++++\n", __func__);  element = gst_bin_new ("vbin");  conv = gst_element_factory_make ("ffmpegcolorspace", "conv");  //sink = gst_element_factory_make ("xvimagesink", "sink");  sink = gst_element_factory_make("autovideosink", "sink");  media.videosink = sink;  gst_bin_add (GST_BIN (element), conv);  gst_bin_add (GST_BIN (element), sink);  gst_element_link_pads (conv, "src", sink, "sink");  pad = gst_element_get_pad (conv, "sink");  gst_element_add_pad (element, gst_ghost_pad_new ("sink", pad));  if (GST_IS_BIN (sink))   {    g_signal_connect (sink, "element-added",                      G_CALLBACK (got_new_video_sink_bin_element), NULL);  }  gst_object_unref (pad);  return element;}/////////////////////////////////////////////////////descriptor: create audio pad.//para://return value://////////////////////////////////////////////////static GstElement *audio_create(){  GstElement *element;  GstElement *conv;  GstElement *sink;  GstPad *pad;  printf("	++++ %s ++++\n", __func__);  element = gst_bin_new ("abin");  conv = gst_element_factory_make ("audioconvert", "conv");  sink = gst_element_factory_make ("alsasink", "sink");  gst_bin_add (GST_BIN (element), conv);  gst_bin_add (GST_BIN (element), sink);  gst_element_link_pads (conv, "src", sink, "sink");  pad = gst_element_get_pad (conv, "sink");  gst_element_add_pad (element, gst_ghost_pad_new ("sink", pad));  gst_object_unref (pad);  return element;}/////////////////////////////////////////////////////descriptor: make pad for audio and video.//para://return value://////////////////////////////////////////////////static void create_pad (GstElement * decodebin, GstPad * pad, gboolean last, gpointer data){  GstCaps *caps;  GstStructure *str;  GstPad *sinkpad;  GstElement *sink;  GstElement *pipeline;  const gchar *name;  GstStateChangeReturn ret;  GstPadLinkReturn lret;  printf("	++++ %s ++++\n", __func__);  /* check media type */  caps = gst_pad_get_caps (pad);  str = gst_caps_get_structure (caps, 0);  name = gst_structure_get_name (str);  g_print ("name: %s\n", name);  if (g_strrstr (name, "audio"))   {    sink = audio_create ();  }   else if (g_strrstr (name, "video"))   {    sink = video_create();  }   else   {    sink = NULL;  }  gst_caps_unref (caps);  if (sink)   {    pipeline = GST_ELEMENT_CAST (data);    /* add new sink to the pipeline */    gst_bin_add (GST_BIN_CAST (pipeline), sink);    /* set the new sink tp PAUSED as well */    ret = gst_element_set_state (sink, GST_STATE_PAUSED);    if (ret == GST_STATE_CHANGE_FAILURE)      goto gsterror;    /* get the ghostpad of the sink bin */    sinkpad = gst_element_get_pad (sink, "sink");    /* link'n'play */    lret = gst_pad_link (pad, sinkpad);    if (lret != GST_PAD_LINK_OK)      goto linkfail;    gst_object_unref (sinkpad);  }  return;  /* ERRORS */gsterror:  {    gst_bin_remove (GST_BIN_CAST (pipeline), sink);    g_warning ("could not change state of new sink (%d)", ret);    return;  }  linkfail:  {    g_warning ("could not link pad and sink (%d)", lret);    return;  }}/////////////////////////////////////////////////////descriptor: event process.//para://return value://////////////////////////////////////////////////static void event_loop (){  GstBus *bus;  GstMessage *message = NULL;  printf("	++++ %s ++++\n", __func__);  bus = gst_element_get_bus (GST_ELEMENT (media.g_pipe));  while (TRUE) {    message = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);    g_assert (message != NULL);    switch (message->type) {      case GST_MESSAGE_EOS:        gst_message_unref (message);        return;      case GST_MESSAGE_WARNING:      case GST_MESSAGE_ERROR:{        GError *gerror;        gchar *debug;        gst_message_parse_error (message, &gerror, &debug);        gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);        gst_message_unref (message);        g_error_free (gerror);        g_free (debug);        return;      }      default:        gst_message_unref (message);        break;    }  }}/////////////////////////////////////////////////////descriptor: init gstreamer and make a pipeline//para://return value://////////////////////////////////////////////////gint start_gstreamer(gchar *filename){  GstElement *filesrc, *decodebin;  GstStateChangeReturn res;  static GMainLoop *loop;  printf("	++++ %s ++++\n", __func__);  //g_printf("your file name is: %s. \n", filename);    //gst_init (&argc, &argv);  gst_init(NULL, NULL);  gst_local_init();		// for audio and video.  media.g_pipe = gst_pipeline_new ("pipeline");  filesrc = gst_element_factory_make ("filesrc", "filesrc");  g_assert (filesrc);  decodebin = gst_element_factory_make ("decodebin", "decodebin");  g_assert (decodebin);  g_signal_connect (G_OBJECT(decodebin), "new-decoded-pad",   	G_CALLBACK(create_pad), media.g_pipe);  gst_bin_add_many (GST_BIN (media.g_pipe), filesrc, decodebin, NULL);  gst_element_link (filesrc, decodebin);  //if (argc < 2)   //{  //  g_print ("usage: %s <uri>\n", argv[0]);  //  exit (-1);  //}  //g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);  g_object_set (G_OBJECT (filesrc), "location", filename, NULL);  /* set to paused, decodebin will autoplug and signal new_pad callbacks */  res = gst_element_set_state (media.g_pipe, GST_STATE_PAUSED);  if (res == GST_STATE_CHANGE_FAILURE)   {    g_print ("could not pause\n");    return -1;  }    /* wait for paused to complete */  res = gst_element_get_state (media.g_pipe, NULL, NULL, GST_CLOCK_TIME_NONE);  if (res == GST_STATE_CHANGE_FAILURE)   {    g_print ("could not pause\n");    return -1;  }  /* play, now all the sinks are added to the pipeline and are prerolled and ready to play. */  res = gst_element_set_state (media.g_pipe, GST_STATE_PLAYING);  if (res == GST_STATE_CHANGE_FAILURE)  {    g_print ("could not play\n");    return -1;  }  //set video parameter.  //gst_set_video_parameter();  #ifdef DEBUG_GST  g_timeout_add(6000, (GSourceFunc)check_other_function, filename);  //event_loop ();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -