summaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
Diffstat (limited to 'image')
-rw-r--r--image/video.c202
-rw-r--r--image/video.h26
2 files changed, 228 insertions, 0 deletions
diff --git a/image/video.c b/image/video.c
new file mode 100644
index 000000000..2255208c3
--- /dev/null
+++ b/image/video.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gst/gst.h>
+
+#include "content/content_factory.h"
+#include "content/content_protected.h"
+#include "image/video.h"
+#include "utils/talloc.h"
+
+typedef struct nsvideo_content {
+ struct content base;
+
+ GstElement *playbin;
+ GstElement *appsrc;
+} nsvideo_content;
+
+static gboolean nsvideo_bus_call(GstBus *bus, GstMessage *msg,
+ nsvideo_content *video)
+{
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_ERROR:
+ break;
+ case GST_MESSAGE_EOS:
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static void nsvideo_need_data_event(GstElement *playbin, guint size,
+ nsvideo_content *video)
+{
+}
+
+static void nsvideo_enough_data_event(GstElement *playbin,
+ nsvideo_content *video)
+{
+}
+
+static void nsvideo_source_event(GObject *object, GObject *orig,
+ GParamSpec *pspec, nsvideo_content *video)
+{
+ g_object_get(orig, pspec->name, &video->appsrc, NULL);
+
+ g_signal_connect(video->appsrc, "need-data",
+ G_CALLBACK(nsvideo_need_data_event), video);
+ g_signal_connect(video->appsrc, "enough-data",
+ G_CALLBACK(nsvideo_enough_data_event), video);
+}
+
+static nserror nsvideo_create(const content_handler *handler,
+ lwc_string *imime_type, const http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset, bool quirks,
+ struct content **c)
+{
+ nsvideo_content *video;
+ nserror error;
+ GstBus *bus;
+
+ video = talloc_zero(0, nsvideo_content);
+ if (video == NULL)
+ return NSERROR_NOMEM;
+
+ error = content__init(&video->base, handler, imime_type, params,
+ llcache, fallback_charset, quirks);
+ if (error != NSERROR_OK) {
+ talloc_free(video);
+ return error;
+ }
+
+ error = llcache_handle_force_stream(llcache);
+ if (error != NSERROR_OK) {
+ talloc_free(video);
+ return error;
+ }
+
+ video->playbin = gst_element_factory_make("playbin2", NULL);
+ if (video->playbin == NULL) {
+ talloc_free(video);
+ return NSERROR_NOMEM;
+ }
+
+ bus = gst_pipeline_get_bus(GST_PIPELINE(video->playbin));
+ gst_bus_add_watch(bus, (GstBusFunc) nsvideo_bus_call, video);
+ gst_object_unref(bus);
+
+ g_object_set(video->playbin, "uri", "appsrc://", NULL);
+ g_signal_connect(video->playbin, "deep-notify::source",
+ G_CALLBACK(nsvideo_source_event), video);
+
+ /** \todo Create appsink & register with playbin */
+
+ gst_element_set_state(video->playbin, GST_STATE_PLAYING);
+
+ *c = (struct content *) video;
+
+ return NSERROR_OK;
+}
+
+static bool nsvideo_process_data(struct content *c, const char *data,
+ unsigned int size)
+{
+ nsvideo_content *video = (nsvideo_content *) c;
+ GstBuffer *buffer;
+ GstFlowReturn ret;
+
+ buffer = gst_buffer_new();
+ GST_BUFFER_DATA(buffer) = (guint8 *) data;
+ GST_BUFFER_SIZE(buffer) = (gsize) size;
+
+ /* Send data to appsrc */
+ g_signal_emit_by_name(video->appsrc, "push-buffer", buffer, &ret);
+
+ return ret == GST_FLOW_OK;
+}
+
+static bool nsvideo_convert(struct content *c)
+{
+ nsvideo_content *video = (nsvideo_content *) c;
+ GstFlowReturn ret;
+
+ /* Tell appsrc we're done */
+ g_signal_emit_by_name(video->appsrc, "end-of-stream", &ret);
+
+ /* Appsink will flag DONE on receipt of first frame */
+
+ return ret == GST_FLOW_OK;
+}
+
+static void nsvideo_destroy(struct content *c)
+{
+ nsvideo_content *video = (nsvideo_content *) c;
+
+ gst_element_set_state(video->playbin, GST_STATE_NULL);
+ gst_object_unref(video->playbin);
+}
+
+static bool nsvideo_redraw(struct content *c, struct content_redraw_data *data,
+ const struct rect *clip, const struct redraw_context *ctx)
+{
+ /** \todo Implement */
+ return true;
+}
+
+static nserror nsvideo_clone(const struct content *old, struct content **newc)
+{
+ /** \todo Implement */
+ return NSERROR_CLONE_FAILED;
+}
+
+static content_type nsvideo_type(void)
+{
+ /** \todo Lies */
+ return CONTENT_IMAGE;
+}
+
+static void *nsvideo_get_internal(const struct content *c, void *context)
+{
+ /** \todo Return pointer to bitmap containing current frame, if any? */
+ return NULL;
+}
+
+static const content_handler nsvideo_content_handler = {
+ .create = nsvideo_create,
+ .process_data = nsvideo_process_data,
+ .data_complete = nsvideo_convert,
+ .destroy = nsvideo_destroy,
+ .redraw = nsvideo_redraw,
+ .clone = nsvideo_clone,
+ .type = nsvideo_type,
+ .get_internal = nsvideo_get_internal,
+ /* Can't share videos because we stream them */
+ .no_share = true
+};
+
+static const char *nsvideo_types[] = {
+ "video/mp4",
+ "video/webm"
+};
+
+CONTENT_FACTORY_REGISTER_TYPES(nsvideo, nsvideo_types,
+ nsvideo_content_handler);
+
diff --git a/image/video.h b/image/video.h
new file mode 100644
index 000000000..376c837ba
--- /dev/null
+++ b/image/video.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_IMAGE_VIDEO_H_
+#define NETSURF_IMAGE_VIDEO_H_
+
+#include "utils/errors.h"
+
+nserror nsvideo_init(void);
+
+#endif