Accessing video RGB data

Sami Pietila sami.pietila at gmail.com
Sat Oct 1 01:16:11 PDT 2011


Hi,

I am trying to access RGB data of image frames in a mov -file. Below
is code that I have constructed using gstreamer examples and
documentation. cb_have_data() doesn't seem to give me RGB data. I am
setting the data to 0 (=black?), but I can see shortly a green screen
on the video and then comes invalid pointer error.

How can I read RGB data from a video, frame by frame? I need also a
way to control the flow of frames, in a way that once I have done with
processing one frame I could ask gstreamer to give me next frame. Code
examples would be great.

Thanks


#include <iostream>
#include <gst/gst.h>

GstElement *pipeline, *video;

static gboolean
cb_have_data (GstPad *pad, GstBuffer *buffer, gpointer u_data) {

  guint16 *data = (guint16 *) GST_BUFFER_DATA (buffer);
  GstCaps *caps = gst_buffer_get_caps(buffer);

  char m_width[] = "width";
  char m_height[] = "height";

  GstStructure *structure = gst_caps_get_structure(caps, 0);

  const GValue *width_gval = gst_structure_get_value(structure, m_width);
  const GValue *height_gval = gst_structure_get_value(structure, m_height);

  int width = g_value_get_int (width_gval);
  int height = g_value_get_int(height_gval);

  for (int y = 0; y < height; y++) {
	  for (int x = 0; x < width; x++) {
		  data[width*y + x] = 0;
	  }
  }

  return TRUE;
}

static void
cb_newpad (GstElement *decodebin,
	   GstPad     *pad,
	   gboolean    last,
	   gpointer    data)
{
  GstCaps *caps;
  GstStructure *str;
  GstPad *videopad;

  videopad = gst_element_get_static_pad (video, "sink");
  if (GST_PAD_IS_LINKED (videopad)) {
    g_object_unref (videopad);
    return;
  }

  caps = gst_pad_get_caps (pad);
  str = gst_caps_get_structure (caps, 0);
  if (!g_strrstr (gst_structure_get_name (str), "video")) {
    gst_caps_unref (caps);
    gst_object_unref (videopad);
    return;
  }
  gst_caps_unref (caps);

  gst_pad_link (pad, videopad);

  g_object_unref (videopad);
}

gint main (gint argc, gchar *argv[])
{
  GMainLoop *loop;
  GstElement *src, *dec, *filter, *cs, *sink;
  GstPad *videopad;
  GstBus *bus;

  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  pipeline = gst_pipeline_new ("pipeline");

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  src = gst_element_factory_make ("filesrc", "source");
  g_object_set (G_OBJECT (src), "location",
"/home/sammy/src/SamScanPlus/src/testi.mov", NULL);
  dec = gst_element_factory_make ("decodebin", "decoder");
  g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
  gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
  gst_element_link (src, dec);

  video = gst_bin_new ("videobin");
  cs = gst_element_factory_make ("ffmpegcolorspace", "cs");
  videopad = gst_element_get_static_pad (cs, "sink");
  sink = gst_element_factory_make ("xvimagesink", "sink");
  gst_bin_add_many (GST_BIN (video), cs, sink, NULL);
  gst_element_link_many(cs, sink, NULL);
  gst_element_add_pad (video, gst_ghost_pad_new ("sink", videopad));
  gst_object_unref (videopad);
  gst_bin_add (GST_BIN (pipeline), video);

  GstPad *pad = gst_element_get_pad (cs, "src");
  gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
  gst_object_unref (pad);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);

  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}


More information about the gstreamer-devel mailing list