Display video via an appsink.
authorXavi Artigas <xartigas@fluendo.com>
Fri, 14 Sep 2012 10:02:19 +0000 (12:02 +0200)
committerXavi Artigas <xartigas@fluendo.com>
Fri, 14 Sep 2012 10:02:19 +0000 (12:02 +0200)
gst-sdk/tutorials/android-tutorial-1/jni/tutorial-1.c

index c5d037d..6229c3b 100755 (executable)
@@ -147,18 +147,53 @@ static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
   }
 }
 
+static void new_buffer (GstElement *sink, CustomData *data) {
+  GstBuffer *buffer;
+   
+  /* Retrieve the buffer */
+  g_signal_emit_by_name (sink, "pull-buffer", &buffer);
+  if (buffer) {
+    if (data->native_window) {
+      int i;
+      ANativeWindow_Buffer nbuff;
+      GstStructure *str;
+      gint width, height;
+
+      str = gst_caps_get_structure (GST_BUFFER_CAPS (buffer), 0);
+      gst_structure_get_int (str, "width", &width);
+      gst_structure_get_int (str, "height", &height);
+
+      ANativeWindow_setBuffersGeometry(data->native_window, width, height, WINDOW_FORMAT_RGBX_8888);
+
+      ANativeWindow_lock(data->native_window, &nbuff, NULL);
+      GST_DEBUG ("Native buffer width:%d height:%d stride:%d format:%d", nbuff.width, nbuff.height, nbuff.stride, nbuff.format);
+      for (i=0; i<nbuff.height; i++) {
+        memcpy (nbuff.bits + nbuff.stride * 4 * i, GST_BUFFER_DATA (buffer) + width * 4 * i, width * 4);
+      }
+      ANativeWindow_unlockAndPost (data->native_window);
+    }
+    gst_buffer_unref (buffer);
+  }
+}
+
 static void *app_function (void *userdata) {
   JavaVMAttachArgs args;
   GstBus *bus;
   GstMessage *msg;
   CustomData *data = (CustomData *)userdata;
+  GstElement *vsink;
 
   GST_DEBUG ("Creating pipeline in CustomData at %p", data);
 
 //  data->pipeline = gst_parse_launch ("videotestsrc ! eglglessink force_rendering_slow=1 can_create_window=0", NULL);
 //  data->pipeline = gst_parse_launch ("filesrc location=/sdcard/Movies/sintel_trailer-480p.ogv ! oggdemux ! theoradec ! fakesink", NULL);
-  data->pipeline = gst_parse_launch ("souphttpsrc location=http://docs.gstreamer.com/media/sintel_trailer-480p.ogv ! oggdemux ! theoradec ! fakesink", NULL);
+//  data->pipeline = gst_parse_launch ("souphttpsrc location=http://docs.gstreamer.com/media/sintel_trailer-480p.ogv ! oggdemux ! theoradec ! fakesink", NULL);
+//  data->pipeline = gst_parse_launch ("videotestsrc ! ffmpegcolorspace ! appsink name=vsink emit-signals=1 caps=video/x-raw-rgb,bpp=(int)32,endianness=(int)4321,depth=(int)24,red_mask=(int)-16777216,green_mask=(int)16711680,blue_mask=(int)65280,width=(int)320,height=(int)240,framerate=(fraction)30/1", NULL);
+  data->pipeline = gst_parse_launch ("souphttpsrc location=http://docs.gstreamer.com/media/sintel_trailer-480p.ogv ! oggdemux ! theoradec ! ffmpegcolorspace ! appsink name=vsink emit-signals=1 caps=video/x-raw-rgb,bpp=(int)32,endianness=(int)4321,depth=(int)24,red_mask=(int)-16777216,green_mask=(int)16711680,blue_mask=(int)65280", NULL);
 
+  vsink = gst_bin_get_by_name (GST_BIN (data->pipeline), "vsink");
+  g_signal_connect (vsink, "new-buffer", G_CALLBACK (new_buffer), data);
+  gst_object_unref (vsink);
 
   /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
   bus = gst_element_get_bus (data->pipeline);