GStreamer播放教程05——色彩平衡

来源:互联网 发布:php在服务器怎么打开 编辑:程序博客网 时间:2024/05/10 04:18

原文:https://gstreamer.freedesktop.org/documentation/tutorials/playback/index.html

译文原文:http://blog.csdn.net/sakulafly/article/details/22692265

原码:Git clone Git://anongit.freedesktop.org/gstreamer/gst-docs

编译:gcc playback-tutorial-5.c -o playback-tutorial-5 `pkg-config --cflags --libs gstreamer-video-1.0 gstreamer-1.0`


If you need help to compile this code, refer to the Building the tutorials section for your platform: Mac or Windows or use this specific command on Linux:

gcc playback-tutorial-5.c -o playback-tutorial-5 `pkg-config --cflags --libs gstreamer-1.0 gstreamer-video-1.0`

If you need help to run this code, refer to the Running the tutorials section for your platform: Mac OS X, Windows, for iOS or for android.

This tutorial opens a window and displays a movie, with accompanying audio. The media is fetched from the Internet, so the window might take a few seconds to appear, depending on your connection speed.

The console should print all commands (Each command is a single upper-case or lower-case letter) and list all available Color Balance channels, typically, CONTRAST, BRIGHTNESS, HUE and SATURATION. Type each command (letter) followed by the Enter key.

Required libraries: gstreamer-1.0 gstreamer-video-1.0


目标

      亮度,对比度,色度和饱和度都是常见的视频调节参数,也是GStreamer里面设置色彩平衡的参数。本教程将展示:

      如何发现可用的色彩平衡通道

      如何改变它们


介绍

      《GStreamer基础教程05——集成GUI工具》里面已经解释了GObject接口:应用通过它们来获得特定功能,而不用去管具体的element的实现。

      playbin2实现了色彩平衡的接口(gstcolorbalance),这就可以设置色彩平衡了。如果playbin2里面的任何一个element支持了这个接口,playbin2就仅仅简单地把应用的设置传给element,否则就会在pipeline中增加一个色彩平衡的element。

      这个接口允许查询可用的色彩平衡通道(gstcolorbalancechannel),包括它们的名字和值得有效区间,然后调整当前的值。


色彩平衡例子

#include <string.h>#include <gst/gst.h>#include <gst/interfaces/colorbalance.h>  typedef struct _CustomData {  GstElement *pipeline;  GMainLoop *loop;} CustomData;  /* Process a color balance command */static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) {  gdouble step;  gint value;  GstColorBalanceChannel *channel = NULL;  const GList *channels, *l;    /* Retrieve the list of channels and locate the requested one */  channels = gst_color_balance_list_channels (cb);  for (l = channels; l != NULL; l = l->next) {    GstColorBalanceChannel *tmp = (GstColorBalanceChannel *)l->data;        if (g_strrstr (tmp->label, channel_name)) {      channel = tmp;      break;    }  }  if (!channel)    return;    /* Change the channel's value */  step = 0.1 * (channel->max_value - channel->min_value);  value = gst_color_balance_get_value (cb, channel);  if (increase) {    value = (gint)(value + step);    if (value > channel->max_value)      value = channel->max_value;  } else {    value = (gint)(value - step);    if (value < channel->min_value)      value = channel->min_value;  }  gst_color_balance_set_value (cb, channel, value);}  /* Output the current values of all Color Balance channels */static void print_current_values (GstElement *pipeline) {  const GList *channels, *l;    /* Output Color Balance values */  channels = gst_color_balance_list_channels (GST_COLOR_BALANCE (pipeline));  for (l = channels; l != NULL; l = l->next) {    GstColorBalanceChannel *channel = (GstColorBalanceChannel *)l->data;    gint value = gst_color_balance_get_value (GST_COLOR_BALANCE (pipeline), channel);    g_print ("%s: %3d%% ", channel->label,        100 * (value - channel->min_value) / (channel->max_value - channel->min_value));  }  g_print ("\n");}  /* Process keyboard input */static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) {  gchar *str = NULL;    if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) {    return TRUE;  }    switch (g_ascii_tolower (str[0])) {  case 'c':    update_color_channel ("CONTRAST", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline));    break;  case 'b':    update_color_channel ("BRIGHTNESS", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline));    break;  case 'h':    update_color_channel ("HUE", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline));    break;  case 's':    update_color_channel ("SATURATION", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline));    break;  case 'q':    g_main_loop_quit (data->loop);    break;  default:    break;  }    g_free (str);    print_current_values (data->pipeline);    return TRUE;}  int main(int argc, char *argv[]) {  CustomData data;  GstStateChangeReturn ret;  GIOChannel *io_stdin;     /* Initialize GStreamer */  gst_init (&argc, &argv);    /* Initialize our data structure */  memset (&data, 0, sizeof (data));    /* Print usage map */  g_print (    "USAGE: Choose one of the following options, then press enter:\n"    " 'C' to increase contrast, 'c' to decrease contrast\n"    " 'B' to increase brightness, 'b' to decrease brightness\n"    " 'H' to increase hue, 'h' to decrease hue\n"    " 'S' to increase saturation, 's' to decrease saturation\n"    " 'Q' to quit\n");    /* Build the pipeline */  data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);    /* Add a keyboard watch so we get notified of keystrokes */#ifdef _WIN32  io_stdin = g_io_channel_win32_new_fd (fileno (stdin));#else  io_stdin = g_io_channel_unix_new (fileno (stdin));#endif  g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);    /* Start playing */  ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);  if (ret == GST_STATE_CHANGE_FAILURE) {    g_printerr ("Unable to set the pipeline to the playing state.\n");    gst_object_unref (data.pipeline);    return -1;  }  print_current_values (data.pipeline);     /* Create a GLib Main Loop and set it to run */  data.loop = g_main_loop_new (NULL, FALSE);  g_main_loop_run (data.loop);    /* Free resources */  g_main_loop_unref (data.loop);  g_io_channel_unref (io_stdin);  gst_element_set_state (data.pipeline, GST_STATE_NULL);  gst_object_unref (data.pipeline);  return 0;}

工作流程

      main()函数非常的简单。用一个playbin2的建立pipeline,注册一个键盘处理函数来监控按键。

/* Output the current values of all Color Balance channels */static void print_current_values (GstElement *pipeline) {  const GList *channels, *l;    /* Output Color Balance values */  channels = gst_color_balance_list_channels (GST_COLOR_BALANCE (pipeline));  for (l = channels; l != NULL; l = l->next) {    GstColorBalanceChannel *channel = (GstColorBalanceChannel *)l->data;    gint value = gst_color_balance_get_value (GST_COLOR_BALANCE (pipeline), channel);    g_print ("%s: %3d%% ", channel->label,        100 * (value - channel->min_value) / (channel->max_value - channel->min_value));  }  g_print ("\n");}

      这个方法展示了如何获得通道的列表并打印所有通道当前的值。这是通过gst_color_balance_list_channels()方法来实现的,它会返回一个GList结构,我们遍历这个结构即可。

      在这个列表里面的每一个element都是GstColorBalanceChannel结构,包括通道名,最小值和最大值。然后就可以在每个通道调用gst_color_balance_get_value()方法来获得当前值。

      在这个例子中,当前值常常用占最大值的百分比来显示。

/* Process a color balance command */static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) {  gdouble step;  gint value;  GstColorBalanceChannel *channel = NULL;  const GList *channels, *l;    /* Retrieve the list of channels and locate the requested one */  channels = gst_color_balance_list_channels (cb);  for (l = channels; l != NULL; l = l->next) {    GstColorBalanceChannel *tmp = (GstColorBalanceChannel *)l->data;        if (g_strrstr (tmp->label, channel_name)) {      channel = tmp;      break;    }  }  if (!channel)    return;

      这个方法通过指定通道名来确定通道,然后根据操作增加或者减少值。另外,通道列表的获得后是根据指定的名字来解析获得通道的。很显然,这个列表只应该解析一次,指向通道的指针需要保持在比一个字符串更高效的数据结构中。


Conclusion

This tutorial has shown how to use the color balance interface. Particularly, it has shown:

  • How to retrieve the list of color available balance channels with gst_color_balance_list_channels()
  • How to manipulate the current value of each channel using gst_color_balance_get_value() and gst_color_balance_set_value()

It has been a pleasure having you here, and see you soon!

0 0
原创粉丝点击