From d3f174f77f25c66f14d2036a80e334a95c081691 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 16 Dec 2018 23:45:32 +0000 Subject: [PATCH] Remove daala plugin Not so useful now that all effort is focused on AV1 instead. Was only ever enabled with --enable-experimental anyway. Fixes #848 --- configure.ac | 16 - docs/plugins/gst-plugins-bad-plugins.args | 20 - docs/plugins/gst-plugins-bad-plugins.interfaces | 1 - ext/Makefile.am | 8 - ext/daala/Makefile.am | 19 - ext/daala/gstdaala.c | 42 -- ext/daala/gstdaaladec.c | 658 -------------------- ext/daala/gstdaaladec.h | 84 --- ext/daala/gstdaalaenc.c | 769 ------------------------ ext/daala/gstdaalaenc.h | 88 --- ext/meson.build | 1 - 11 files changed, 1706 deletions(-) delete mode 100644 ext/daala/Makefile.am delete mode 100644 ext/daala/gstdaala.c delete mode 100644 ext/daala/gstdaaladec.c delete mode 100644 ext/daala/gstdaaladec.h delete mode 100644 ext/daala/gstdaalaenc.c delete mode 100644 ext/daala/gstdaalaenc.h diff --git a/configure.ac b/configure.ac index 0878e6e..ef8692d 100644 --- a/configure.ac +++ b/configure.ac @@ -1357,20 +1357,6 @@ AG_GST_CHECK_FEATURE(WEBP, [WebP], webp , [ AC_SUBST(WEBP_LIBS) ]) -dnl *** Daala *** -translit(dnm, m, l) AM_CONDITIONAL(USE_DAALA, true) -AG_GST_CHECK_FEATURE(DAALA, [daala], daala, [ - if test "x$BUILD_EXPERIMENTAL" = "xyes"; then - PKG_CHECK_MODULES(DAALA, daalaenc daaladec, [ - HAVE_DAALA="yes" - ], [ - HAVE_DAALA="no" - ]) - AC_SUBST(DAALA_CFLAGS) - AC_SUBST(DAALA_LIBS) - fi -]) - dnl *** DTS *** translit(dnm, m, l) AM_CONDITIONAL(USE_DTS, true) AG_GST_CHECK_FEATURE(DTS, [dts library], dtsdec, [ @@ -2376,7 +2362,6 @@ AM_CONDITIONAL(DECKLINK_OSX, false) AM_CONDITIONAL(DECKLINK_WIN, false) AM_CONDITIONAL(USE_DIRECTFB, false) AM_CONDITIONAL(USE_WAYLAND, false) -AM_CONDITIONAL(USE_DAALA, false) AM_CONDITIONAL(USE_DTS, false) AM_CONDITIONAL(USE_EXIF, false) AM_CONDITIONAL(USE_RESINDVD, false) @@ -2685,7 +2670,6 @@ ext/dash/Makefile ext/dc1394/Makefile ext/directfb/Makefile ext/wayland/Makefile -ext/daala/Makefile ext/dts/Makefile ext/faac/Makefile ext/faad/Makefile diff --git a/docs/plugins/gst-plugins-bad-plugins.args b/docs/plugins/gst-plugins-bad-plugins.args index f216c48..04cab22 100644 --- a/docs/plugins/gst-plugins-bad-plugins.args +++ b/docs/plugins/gst-plugins-bad-plugins.args @@ -59803,26 +59803,6 @@ Gestures in the defined region of interest will emit messages. -GstDaalaEnc::keyframe-rate -gint ->= 1 -rw -Keyframe Rate -Keyframe Rate. -1 - - - -GstDaalaEnc::quant -gint -[0,511] -rw -Quant -Quant. -10 - - - ladspasrc-sin-cos-1881-so-sincos::base-frequency gfloat [0.0441,22050] diff --git a/docs/plugins/gst-plugins-bad-plugins.interfaces b/docs/plugins/gst-plugins-bad-plugins.interfaces index 24851c70..25083c4 100644 --- a/docs/plugins/gst-plugins-bad-plugins.interfaces +++ b/docs/plugins/gst-plugins-bad-plugins.interfaces @@ -22,7 +22,6 @@ GstCameraBin2 GstChildProxy GstTagSetter GstCeltEnc GstPreset GstTagSetter GstCompositor GstChildProxy GstCurlHttpSrc GstURIHandler -GstDaalaEnc GstPreset GstDashDemux GstChildProxy GstDfbVideoSink GstImplementsInterface GstNavigation GstColorBalance GstDfbVideoSink GstNavigation GstColorBalance diff --git a/ext/Makefile.am b/ext/Makefile.am index 591b48e..31f7932 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -70,12 +70,6 @@ else WAYLAND_DIR= endif -if USE_DAALA -DAALA_DIR=daala -else -DAALA_DIR= -endif - if USE_DTS DTS_DIR=dts else @@ -422,7 +416,6 @@ SUBDIRS=\ $(DC1394_DIR) \ $(DIRECTFB_DIR) \ $(WAYLAND_DIR) \ - $(DAALA_DIR) \ $(DTS_DIR) \ $(RESINDVD_DIR) \ $(GL_DIR) \ @@ -503,7 +496,6 @@ DIST_SUBDIRS = \ libde265 \ libmms \ lv2 \ - daala \ dts \ gl \ modplug \ diff --git a/ext/daala/Makefile.am b/ext/daala/Makefile.am deleted file mode 100644 index c4af0bf..0000000 --- a/ext/daala/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -plugin_LTLIBRARIES = libgstdaala.la - -noinst_HEADERS = gstdaalaenc.h \ - gstdaaladec.h - -libgstdaala_la_SOURCES = gstdaala.c \ - gstdaalaenc.c \ - gstdaaladec.c - -libgstdaala_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(DAALA_CFLAGS) -libgstdaala_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) \ - -lgsttag-$(GST_API_VERSION) \ - -lgstvideo-$(GST_API_VERSION) \ - $(GST_BASE_LIBS) \ - $(GST_LIBS) \ - $(DAALA_LIBS) -libgstdaala_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - diff --git a/ext/daala/gstdaala.c b/ext/daala/gstdaala.c deleted file mode 100644 index f3f26d8..0000000 --- a/ext/daala/gstdaala.c +++ /dev/null @@ -1,42 +0,0 @@ -/* GStreamer - * Copyright (C) 2013 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "gstdaalaenc.h" -#include "gstdaaladec.h" - -static gboolean -plugin_init (GstPlugin * plugin) -{ - gst_daala_enc_register (plugin); - gst_daala_dec_register (plugin); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - daala, - "Daala plugin", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/daala/gstdaaladec.c b/ext/daala/gstdaaladec.c deleted file mode 100644 index fe3d300..0000000 --- a/ext/daala/gstdaaladec.c +++ /dev/null @@ -1,658 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Benjamin Otte - * Copyright (c) 2012 Collabora Ltd. - * Author : Edward Hervey - * Author : Mark Nauwelaerts - * Copyright (c) 2013 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-daaladec - * @title: daaladec - * @see_also: daalaenc, oggdemux - * - * This element decodes daala streams into raw video - * Daala is a royalty-free - * video codec maintained by the Xiph.org - * Foundation. - * - * ## Example pipeline - * |[ - * gst-launch-1.0 -v filesrc location=videotestsrc.ogg ! oggdemux ! daaladec ! xvimagesink - * ]| This example pipeline will decode an ogg stream and decodes the daala video. Refer to - * the daalaenc example to create the ogg file. - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gstdaaladec.h" -#include -#include -#include -#include - -#define GST_CAT_DEFAULT daaladec_debug -GST_DEBUG_CATEGORY_STATIC (daaladec_debug); -GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); - -/* This was removed from the base class, this is used as a - temporary return to signal the need to call _drop_frame, - and does not leave daalaenc. */ -#define GST_CUSTOM_FLOW_DROP GST_FLOW_CUSTOM_SUCCESS_1 - -enum -{ - PROP_0 -}; - -static GstStaticPadTemplate daala_dec_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw, " - "format = (string) { I420, Y444 }, " - "framerate = (fraction) [0/1, MAX], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") - ); - -static GstStaticPadTemplate daala_dec_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-daala") - ); - -#define gst_daala_dec_parent_class parent_class -G_DEFINE_TYPE (GstDaalaDec, gst_daala_dec, GST_TYPE_VIDEO_DECODER); - -static gboolean daala_dec_start (GstVideoDecoder * decoder); -static gboolean daala_dec_stop (GstVideoDecoder * decoder); -static gboolean daala_dec_set_format (GstVideoDecoder * decoder, - GstVideoCodecState * state); -static GstFlowReturn daala_dec_parse (GstVideoDecoder * decoder, - GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos); -static GstFlowReturn daala_dec_handle_frame (GstVideoDecoder * decoder, - GstVideoCodecFrame * frame); -static gboolean daala_dec_decide_allocation (GstVideoDecoder * decoder, - GstQuery * query); - -static GstFlowReturn daala_dec_decode_buffer (GstDaalaDec * dec, - GstBuffer * buf, GstVideoCodecFrame * frame); - -static void -gst_daala_dec_class_init (GstDaalaDecClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS (klass); - - gst_element_class_add_static_pad_template (element_class, - &daala_dec_src_factory); - gst_element_class_add_static_pad_template (element_class, - &daala_dec_sink_factory); - gst_element_class_set_static_metadata (element_class, "Daala video decoder", - "Codec/Decoder/Video", "Decode raw Daala streams to raw YUV video", - "Sebastian Dröge "); - - video_decoder_class->start = GST_DEBUG_FUNCPTR (daala_dec_start); - video_decoder_class->stop = GST_DEBUG_FUNCPTR (daala_dec_stop); - video_decoder_class->set_format = GST_DEBUG_FUNCPTR (daala_dec_set_format); - video_decoder_class->parse = GST_DEBUG_FUNCPTR (daala_dec_parse); - video_decoder_class->handle_frame = - GST_DEBUG_FUNCPTR (daala_dec_handle_frame); - video_decoder_class->decide_allocation = - GST_DEBUG_FUNCPTR (daala_dec_decide_allocation); - - GST_DEBUG_CATEGORY_INIT (daaladec_debug, "daaladec", 0, "Daala decoder"); - GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); -} - -static void -gst_daala_dec_init (GstDaalaDec * dec) -{ - /* input is packetized, - * but is not marked that way so data gets parsed and keyframes marked */ - gst_video_decoder_set_packetized (GST_VIDEO_DECODER (dec), FALSE); - gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (dec), TRUE); - gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST - (dec), TRUE); - GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (dec)); -} - -static void -daala_dec_reset (GstDaalaDec * dec) -{ - dec->need_keyframe = TRUE; -} - -static gboolean -daala_dec_start (GstVideoDecoder * decoder) -{ - GstDaalaDec *dec = GST_DAALA_DEC (decoder); - - GST_DEBUG_OBJECT (dec, "start"); - daala_info_clear (&dec->info); - daala_comment_clear (&dec->comment); - GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE"); - dec->have_header = FALSE; - daala_dec_reset (dec); - - return TRUE; -} - -static gboolean -daala_dec_stop (GstVideoDecoder * decoder) -{ - GstDaalaDec *dec = GST_DAALA_DEC (decoder); - - GST_DEBUG_OBJECT (dec, "stop"); - daala_info_clear (&dec->info); - daala_comment_clear (&dec->comment); - daala_setup_free (dec->setup); - dec->setup = NULL; - daala_decode_free (dec->decoder); - dec->decoder = NULL; - daala_dec_reset (dec); - if (dec->input_state) { - gst_video_codec_state_unref (dec->input_state); - dec->input_state = NULL; - } - if (dec->output_state) { - gst_video_codec_state_unref (dec->output_state); - dec->output_state = NULL; - } - - return TRUE; -} - -static GstFlowReturn -daala_dec_parse (GstVideoDecoder * decoder, - GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos) -{ - gint av; - const guint8 *data; - - av = gst_adapter_available (adapter); - - if (av > 0) { - data = gst_adapter_map (adapter, 1); - /* check for keyframe; must not be header packet */ - if (!(data[0] & 0x80) && (data[0] & 0x40)) { - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); - } - gst_adapter_unmap (adapter); - } - - /* and pass along all */ - gst_video_decoder_add_to_frame (decoder, av); - return gst_video_decoder_have_frame (decoder); -} - - -static gboolean -daala_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state) -{ - GstDaalaDec *dec; - - dec = GST_DAALA_DEC (bdec); - - /* Keep a copy of the input state */ - if (dec->input_state) - gst_video_codec_state_unref (dec->input_state); - dec->input_state = gst_video_codec_state_ref (state); - - /* FIXME : Interesting, we always accept any kind of caps ? */ - if (state->codec_data) { - GstBuffer *buffer; - GstMapInfo minfo; - guint8 *data; - guint size; - guint offset; - - buffer = state->codec_data; - gst_buffer_map (buffer, &minfo, GST_MAP_READ); - - offset = 0; - size = minfo.size; - data = (guint8 *) minfo.data; - - while (size > 2) { - guint psize; - GstBuffer *buf; - - psize = (data[0] << 8) | data[1]; - /* skip header */ - data += 2; - size -= 2; - offset += 2; - - /* make sure we don't read too much */ - psize = MIN (psize, size); - - buf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, psize); - - /* first buffer is a discont buffer */ - if (offset == 2) - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - - /* now feed it to the decoder we can ignore the error */ - daala_dec_decode_buffer (dec, buf, NULL); - gst_buffer_unref (buf); - - /* skip the data */ - size -= psize; - data += psize; - offset += psize; - } - - gst_buffer_unmap (buffer, &minfo); - } - - GST_DEBUG_OBJECT (dec, "Done"); - - return TRUE; -} - -static GstFlowReturn -daala_handle_comment_packet (GstDaalaDec * dec, ogg_packet * packet) -{ - gchar *encoder = NULL; - GstTagList *list; - - GST_DEBUG_OBJECT (dec, "parsing comment packet"); - - list = - gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes, - (guint8 *) "\201daala", 6, &encoder); - - if (!list) { - GST_ERROR_OBJECT (dec, "couldn't decode comments"); - list = gst_tag_list_new_empty (); - } - if (encoder) { - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_ENCODER, encoder, NULL); - g_free (encoder); - } - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_ENCODER_VERSION, dec->info.version_major, - GST_TAG_VIDEO_CODEC, "Daala", NULL); - - gst_video_decoder_merge_tags (GST_VIDEO_DECODER (dec), - list, GST_TAG_MERGE_REPLACE); - - gst_tag_list_unref (list); - - return GST_FLOW_OK; -} - -static GstFlowReturn -daala_handle_type_packet (GstDaalaDec * dec) -{ - gint par_num, par_den; - GstFlowReturn ret = GST_FLOW_OK; - GstVideoCodecState *state; - GstVideoFormat fmt; - GstVideoInfo *info; - - if (!dec->input_state) - return GST_FLOW_NOT_NEGOTIATED; - - info = &dec->input_state->info; - - GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d", - dec->info.timebase_numerator, dec->info.timebase_denominator, - dec->info.pixel_aspect_numerator, dec->info.pixel_aspect_denominator); - - /* calculate par - * the info.aspect_* values reflect PAR; - * 0:x and x:0 are allowed and can be interpreted as 1:1. - */ - par_num = GST_VIDEO_INFO_PAR_N (info); - par_den = GST_VIDEO_INFO_PAR_D (info); - - /* If we have a default PAR, see if the decoder specified a different one */ - if (par_num == 1 && par_den == 1 && - (dec->info.pixel_aspect_numerator != 0 - && dec->info.pixel_aspect_denominator != 0)) { - par_num = dec->info.pixel_aspect_numerator; - par_den = dec->info.pixel_aspect_denominator; - } - /* daala has: - * - * width/height : dimension of the encoded frame - * pic_width/pic_height : dimension of the visible part - * pic_x/pic_y : offset in encoded frame where visible part starts - */ - GST_DEBUG_OBJECT (dec, "dimension %dx%d, PAR %d/%d", dec->info.pic_width, - dec->info.pic_height, par_num, par_den); - - if (dec->info.nplanes == 3 && dec->info.plane_info[0].xdec == 0 && - dec->info.plane_info[0].ydec == 0 && - dec->info.plane_info[1].xdec == 1 && - dec->info.plane_info[1].ydec == 1 && - dec->info.plane_info[2].xdec == 1 && dec->info.plane_info[2].ydec == 1) { - fmt = GST_VIDEO_FORMAT_I420; - } else if (dec->info.nplanes == 3 && dec->info.plane_info[0].xdec == 0 && - dec->info.plane_info[0].ydec == 0 && - dec->info.plane_info[1].xdec == 0 && - dec->info.plane_info[1].ydec == 0 && - dec->info.plane_info[2].xdec == 0 && dec->info.plane_info[2].ydec == 0) { - fmt = GST_VIDEO_FORMAT_Y444; - } else { - goto unsupported_format; - } - - GST_VIDEO_INFO_WIDTH (info) = dec->info.pic_width; - GST_VIDEO_INFO_HEIGHT (info) = dec->info.pic_height; - - /* done */ - dec->decoder = daala_decode_alloc (&dec->info, dec->setup); - - /* Create the output state */ - dec->output_state = state = - gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec), fmt, - info->width, info->height, dec->input_state); - - /* FIXME : Do we still need to set fps/par now that we pass the reference input stream ? */ - state->info.fps_n = dec->info.timebase_numerator; - state->info.fps_d = dec->info.timebase_denominator; - state->info.par_n = par_num; - state->info.par_d = par_den; - - gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec)); - - dec->have_header = TRUE; - - return ret; - - /* ERRORS */ -unsupported_format: - { - GST_ERROR_OBJECT (dec, "Invalid pixel format"); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -daala_handle_header_packet (GstDaalaDec * dec, ogg_packet * packet) -{ - GstFlowReturn res; - int ret; - - GST_DEBUG_OBJECT (dec, "parsing header packet"); - - ret = daala_decode_header_in (&dec->info, &dec->comment, &dec->setup, packet); - if (ret < 0) - goto header_read_error; - - switch (packet->packet[0]) { - case 0x81: - res = daala_handle_comment_packet (dec, packet); - break; - case 0x82: - res = daala_handle_type_packet (dec); - break; - default: - /* ignore */ - g_warning ("unknown daala header packet found"); - case 0x80: - /* nothing special, this is the identification header */ - res = GST_FLOW_OK; - break; - } - return res; - - /* ERRORS */ -header_read_error: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("couldn't read header packet")); - return GST_FLOW_ERROR; - } -} - -/* Allocate buffer and copy image data into Y444 format */ -static GstFlowReturn -daala_handle_image (GstDaalaDec * dec, od_img * img, GstVideoCodecFrame * frame) -{ - GstVideoDecoder *decoder = GST_VIDEO_DECODER (dec); - gint width, height, stride; - GstFlowReturn result; - gint i, comp; - guint8 *dest, *src; - GstVideoFrame vframe; - - result = gst_video_decoder_allocate_output_frame (decoder, frame); - - if (G_UNLIKELY (result != GST_FLOW_OK)) { - GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s", - gst_flow_get_name (result)); - return result; - } - - /* if only libdaala would allow us to give it a destination frame */ - GST_CAT_TRACE_OBJECT (CAT_PERFORMANCE, dec, - "doing unavoidable video frame copy"); - - if (G_UNLIKELY (!gst_video_frame_map (&vframe, &dec->output_state->info, - frame->output_buffer, GST_MAP_WRITE))) - goto invalid_frame; - - for (comp = 0; comp < 3; comp++) { - width = GST_VIDEO_FRAME_COMP_WIDTH (&vframe, comp); - height = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, comp); - stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, comp); - dest = GST_VIDEO_FRAME_COMP_DATA (&vframe, comp); - - src = img->planes[comp].data; - - for (i = 0; i < height; i++) { - memcpy (dest, src, width); - - dest += stride; - src += img->planes[comp].ystride; - } - } - gst_video_frame_unmap (&vframe); - - return GST_FLOW_OK; -invalid_frame: - { - GST_DEBUG_OBJECT (dec, "could not map video frame"); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -daala_handle_data_packet (GstDaalaDec * dec, ogg_packet * packet, - GstVideoCodecFrame * frame) -{ - /* normal data packet */ - od_img img; - gboolean keyframe; - GstFlowReturn result; - - if (G_UNLIKELY (!dec->have_header)) - goto not_initialized; - - /* the second most significant bit of the first data byte is cleared - * for keyframes. We can only check it if it's not a zero-length packet. */ - keyframe = packet->bytes && ((packet->packet[0] & 0x40)); - if (G_UNLIKELY (keyframe)) { - GST_DEBUG_OBJECT (dec, "we have a keyframe"); - dec->need_keyframe = FALSE; - } else if (G_UNLIKELY (dec->need_keyframe)) { - goto dropping; - } - - GST_DEBUG_OBJECT (dec, "parsing data packet"); - - /* this does the decoding */ - if (G_UNLIKELY (daala_decode_packet_in (dec->decoder, &img, packet) < 0)) - goto decode_error; - - if (frame && - (gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (dec), - frame) < 0)) - goto dropping_qos; - - if (G_UNLIKELY ((img.width != dec->info.pic_width - || img.height != dec->info.pic_height))) - goto wrong_dimensions; - - result = daala_handle_image (dec, &img, frame); - - return result; - - /* ERRORS */ -not_initialized: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("no header sent yet")); - return GST_FLOW_ERROR; - } -dropping: - { - GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe"); - return GST_CUSTOM_FLOW_DROP; - } -dropping_qos: - { - GST_WARNING_OBJECT (dec, "dropping frame because of QoS"); - return GST_CUSTOM_FLOW_DROP; - } -decode_error: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, - (NULL), ("daala decoder did not decode data packet")); - return GST_FLOW_ERROR; - } -wrong_dimensions: - { - GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, FORMAT, - (NULL), ("dimensions of image do not match header")); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -daala_dec_decode_buffer (GstDaalaDec * dec, GstBuffer * buf, - GstVideoCodecFrame * frame) -{ - ogg_packet packet; - GstFlowReturn result = GST_FLOW_OK; - GstMapInfo minfo; - - /* make ogg_packet out of the buffer */ - gst_buffer_map (buf, &minfo, GST_MAP_READ); - packet.packet = minfo.data; - packet.bytes = minfo.size; - packet.granulepos = -1; - packet.packetno = 0; /* we don't really care */ - packet.b_o_s = dec->have_header ? 0 : 1; - /* EOS does not matter for the decoder */ - packet.e_o_s = 0; - - GST_LOG_OBJECT (dec, "decode buffer of size %ld", packet.bytes); - - GST_DEBUG_OBJECT (dec, "header=%02x", packet.bytes ? packet.packet[0] : -1); - - /* switch depending on packet type. A zero byte packet is always a data - * packet; we don't dereference it in that case. */ - if (packet.bytes && packet.packet[0] & 0x80) { - if (dec->have_header) { - GST_WARNING_OBJECT (GST_OBJECT (dec), "Ignoring header"); - GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, - GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); - result = GST_CUSTOM_FLOW_DROP; - goto done; - } - result = daala_handle_header_packet (dec, &packet); - /* header packets are not meant to be displayed */ - /* FIXME : This is a temporary hack. The proper fix would be to - * not call _finish_frame() for these types of packets */ - GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, - GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); - } else { - result = daala_handle_data_packet (dec, &packet, frame); - } - -done: - gst_buffer_unmap (buf, &minfo); - - return result; -} - -static GstFlowReturn -daala_dec_handle_frame (GstVideoDecoder * bdec, GstVideoCodecFrame * frame) -{ - GstDaalaDec *dec; - GstFlowReturn res; - - dec = GST_DAALA_DEC (bdec); - - res = daala_dec_decode_buffer (dec, frame->input_buffer, frame); - switch (res) { - case GST_FLOW_OK: - res = gst_video_decoder_finish_frame (bdec, frame); - break; - case GST_CUSTOM_FLOW_DROP: - res = gst_video_decoder_drop_frame (bdec, frame); - break; - default: - gst_video_codec_frame_unref (frame); - break; - } - - return res; -} - -static gboolean -daala_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query) -{ - GstBufferPool *pool; - GstStructure *config; - - if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder, - query)) - return FALSE; - - g_assert (gst_query_get_n_allocation_pools (query) > 0); - gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL); - g_assert (pool != NULL); - - config = gst_buffer_pool_get_config (pool); - if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - } - gst_buffer_pool_set_config (pool, config); - gst_object_unref (pool); - - return TRUE; -} - -gboolean -gst_daala_dec_register (GstPlugin * plugin) -{ - return gst_element_register (plugin, "daaladec", - GST_RANK_PRIMARY, GST_TYPE_DAALA_DEC); -} diff --git a/ext/daala/gstdaaladec.h b/ext/daala/gstdaaladec.h deleted file mode 100644 index ff2a01e..0000000 --- a/ext/daala/gstdaaladec.h +++ /dev/null @@ -1,84 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Benjamin Otte - * Copyright (c) 2012 Collabora Ltd. - * Author : Edward Hervey - * Author : Mark Nauwelaerts - * Copyright (c) 2013 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_DAALADEC_H__ -#define __GST_DAALADEC_H__ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_DAALA_DEC \ - (gst_daala_dec_get_type()) -#define GST_DAALA_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DAALA_DEC,GstDaalaDec)) -#define GST_DAALA_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DAALA_DEC,GstDaalaDecClass)) -#define GST_IS_DAALA_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DAALA_DEC)) -#define GST_IS_DAALA_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DAALA_DEC)) - -typedef struct _GstDaalaDec GstDaalaDec; -typedef struct _GstDaalaDecClass GstDaalaDecClass; - -/** - * GstDaalaDec: - * - * Opaque object data structure. - */ -struct _GstDaalaDec -{ - GstVideoDecoder element; - - /* daala decoder state */ - daala_dec_ctx *decoder; - daala_setup_info *setup; - daala_info info; - daala_comment comment; - - gboolean have_header; - - gboolean need_keyframe; - GstVideoCodecState *input_state; - GstVideoCodecState *output_state; -}; - -struct _GstDaalaDecClass -{ - GstVideoDecoderClass parent_class; -}; - -GType gst_daala_dec_get_type (void); -gboolean gst_daala_dec_register (GstPlugin * plugin); - -G_END_DECLS - -#endif /* __GST_DAALADEC_H__ */ diff --git a/ext/daala/gstdaalaenc.c b/ext/daala/gstdaalaenc.c deleted file mode 100644 index 909f14b..0000000 --- a/ext/daala/gstdaalaenc.c +++ /dev/null @@ -1,769 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * Copyright (c) 2012 Collabora Ltd. - * Author : Edward Hervey - * Author : Mark Nauwelaerts - * Copyright (c) 2013 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-daalaenc - * @title: daalaenc - * @see_also: daaladec, oggmux - * - * This element encodes raw video into a Daala stream. - * Daala is a royalty-free - * video codec maintained by the Xiph.org - * Foundation. - * - * ## Example pipeline - * |[ - * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! daalaenc ! oggmux ! filesink location=videotestsrc.ogg - * ]| This example pipeline will encode a test video source to daala muxed in an - * ogg container. Refer to the daaladec documentation to decode the create - * stream. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include /* free */ - -#include -#include -#include - -#include "gstdaalaenc.h" - -#define GST_CAT_DEFAULT daalaenc_debug -GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); - -enum -{ - PROP_0, - PROP_QUANT, - PROP_KEYFRAME_RATE -}; - -#define DEFAULT_QUANT 10 -#define DEFAULT_KEYFRAME_RATE 1 - -static GstStaticPadTemplate daala_enc_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, Y444 }")) - ); - -static GstStaticPadTemplate daala_enc_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-daala, " - "framerate = (fraction) [1/MAX, MAX], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") - ); - -static GstCaps *daala_supported_caps = NULL; - -#define gst_daala_enc_parent_class parent_class -G_DEFINE_TYPE (GstDaalaEnc, gst_daala_enc, GST_TYPE_VIDEO_ENCODER); - -static gboolean daala_enc_start (GstVideoEncoder * enc); -static gboolean daala_enc_stop (GstVideoEncoder * enc); -static gboolean daala_enc_flush (GstVideoEncoder * enc); -static gboolean daala_enc_set_format (GstVideoEncoder * enc, - GstVideoCodecState * state); -static GstFlowReturn daala_enc_handle_frame (GstVideoEncoder * enc, - GstVideoCodecFrame * frame); -static GstFlowReturn daala_enc_pre_push (GstVideoEncoder * benc, - GstVideoCodecFrame * frame); -static GstFlowReturn daala_enc_finish (GstVideoEncoder * enc); -static gboolean daala_enc_propose_allocation (GstVideoEncoder * encoder, - GstQuery * query); -static gboolean gst_daala_enc_sink_query (GstVideoEncoder * encoder, - GstQuery * query); - -static GstCaps *daala_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter); -static void daala_enc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void daala_enc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void daala_enc_finalize (GObject * object); - -static char * -daala_enc_get_supported_formats (void) -{ - daala_enc_ctx *encoder; - daala_info info; - struct - { - GstVideoFormat fmt; - gint planes; - gint xdec[3], ydec[3]; - } formats[] = { - { - GST_VIDEO_FORMAT_Y444, 3, { - 0, 0, 0}, { - 0, 0, 0}}, { - GST_VIDEO_FORMAT_I420, 3, { - 0, 1, 1}, { - 0, 1, 1}} - }; - GString *string = NULL; - guint i; - - daala_info_init (&info); - info.pic_width = 16; - info.pic_height = 16; - info.timebase_numerator = 25; - info.timebase_denominator = 1; - info.frame_duration = 1; - for (i = 0; i < G_N_ELEMENTS (formats); i++) { - gint j; - - info.nplanes = formats[i].planes; - for (j = 0; j < formats[i].planes; j++) { - info.plane_info[j].xdec = formats[i].xdec[j]; - info.plane_info[j].ydec = formats[i].ydec[j]; - } - - encoder = daala_encode_create (&info); - if (encoder == NULL) - continue; - - GST_LOG ("format %s is supported", - gst_video_format_to_string (formats[i].fmt)); - daala_encode_free (encoder); - - if (string == NULL) { - string = g_string_new (gst_video_format_to_string (formats[i].fmt)); - } else { - g_string_append (string, ", "); - g_string_append (string, gst_video_format_to_string (formats[i].fmt)); - } - } - daala_info_clear (&info); - - return string == NULL ? NULL : g_string_free (string, FALSE); -} - -static void -initialize_supported_caps (void) -{ - char *supported_formats, *caps_string; - - supported_formats = daala_enc_get_supported_formats (); - if (!supported_formats) { - GST_WARNING ("no supported formats found. Encoder disabled?"); - daala_supported_caps = gst_caps_new_empty (); - } - - caps_string = g_strdup_printf ("video/x-raw, " - "format = (string) { %s }, " - "framerate = (fraction) [1/MAX, MAX], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]", - supported_formats); - daala_supported_caps = gst_caps_from_string (caps_string); - g_free (caps_string); - g_free (supported_formats); - GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, daala_supported_caps); -} - -static void -gst_daala_enc_class_init (GstDaalaEncClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstElementClass *element_class = (GstElementClass *) klass; - GstVideoEncoderClass *gstvideo_encoder_class = - GST_VIDEO_ENCODER_CLASS (klass); - - GST_DEBUG_CATEGORY_INIT (daalaenc_debug, "daalaenc", 0, "Daala encoder"); - - gobject_class->set_property = daala_enc_set_property; - gobject_class->get_property = daala_enc_get_property; - gobject_class->finalize = daala_enc_finalize; - - g_object_class_install_property (gobject_class, PROP_QUANT, - g_param_spec_int ("quant", "Quant", "Quant", - 0, 511, DEFAULT_QUANT, - (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_KEYFRAME_RATE, - g_param_spec_int ("keyframe-rate", "Keyframe Rate", "Keyframe Rate", - 1, G_MAXINT, DEFAULT_KEYFRAME_RATE, - (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gst_element_class_add_static_pad_template (element_class, - &daala_enc_src_factory); - gst_element_class_add_static_pad_template (element_class, - &daala_enc_sink_factory); - gst_element_class_set_static_metadata (element_class, "Daala video encoder", - "Codec/Encoder/Video", "Encode raw YUV video to a Daala stream", - "Sebastian Dröge "); - - gstvideo_encoder_class->start = GST_DEBUG_FUNCPTR (daala_enc_start); - gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (daala_enc_stop); - gstvideo_encoder_class->flush = GST_DEBUG_FUNCPTR (daala_enc_flush); - gstvideo_encoder_class->set_format = GST_DEBUG_FUNCPTR (daala_enc_set_format); - gstvideo_encoder_class->handle_frame = - GST_DEBUG_FUNCPTR (daala_enc_handle_frame); - gstvideo_encoder_class->pre_push = GST_DEBUG_FUNCPTR (daala_enc_pre_push); - gstvideo_encoder_class->finish = GST_DEBUG_FUNCPTR (daala_enc_finish); - gstvideo_encoder_class->getcaps = GST_DEBUG_FUNCPTR (daala_enc_getcaps); - gstvideo_encoder_class->sink_query = - GST_DEBUG_FUNCPTR (gst_daala_enc_sink_query); - gstvideo_encoder_class->propose_allocation = - GST_DEBUG_FUNCPTR (daala_enc_propose_allocation); - - initialize_supported_caps (); -} - -static void -gst_daala_enc_init (GstDaalaEnc * enc) -{ - enc->quant = DEFAULT_QUANT; - enc->keyframe_rate = DEFAULT_KEYFRAME_RATE; -} - -static void -daala_enc_finalize (GObject * object) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (object); - - GST_DEBUG_OBJECT (enc, "Finalizing"); - if (enc->encoder) - daala_encode_free (enc->encoder); - daala_comment_clear (&enc->comment); - daala_info_clear (&enc->info); - - if (enc->input_state) - gst_video_codec_state_unref (enc->input_state); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -daala_enc_flush (GstVideoEncoder * benc) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (benc); - int quant; - - GST_OBJECT_LOCK (enc); - quant = enc->quant; - enc->quant_changed = FALSE; - enc->info.keyframe_rate = enc->keyframe_rate; - enc->keyframe_rate_changed = FALSE; - GST_OBJECT_UNLOCK (enc); - - if (enc->encoder) - daala_encode_free (enc->encoder); - enc->encoder = daala_encode_create (&enc->info); - - daala_encode_ctl (enc->encoder, OD_SET_QUANT, &quant, sizeof (int)); - - return TRUE; -} - -static gboolean -daala_enc_start (GstVideoEncoder * benc) -{ - GstDaalaEnc *enc; - - GST_DEBUG_OBJECT (benc, "start: init daala"); - enc = GST_DAALA_ENC (benc); - - enc->packetno = 0; - enc->initialised = FALSE; - - return TRUE; -} - -static gboolean -daala_enc_stop (GstVideoEncoder * benc) -{ - GstDaalaEnc *enc; - - GST_DEBUG_OBJECT (benc, "stop: clearing daala state"); - enc = GST_DAALA_ENC (benc); - - if (enc->encoder) { - daala_encode_free (enc->encoder); - enc->encoder = NULL; - } - daala_comment_clear (&enc->comment); - daala_info_clear (&enc->info); - - if (enc->input_state) - gst_video_codec_state_unref (enc->input_state); - enc->input_state = NULL; - - enc->initialised = FALSE; - - return TRUE; -} - -static gboolean -gst_daala_enc_sink_query (GstVideoEncoder * encoder, GstQuery * query) -{ - gboolean res; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_ACCEPT_CAPS:{ - GstCaps *caps; - - gst_query_parse_accept_caps (query, &caps); - - gst_query_set_accept_caps_result (query, - gst_caps_is_subset (caps, daala_supported_caps)); - res = TRUE; - } - break; - default: - res = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (encoder, query); - break; - } - - return res; -} - -static GstCaps * -daala_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter) -{ - return gst_video_encoder_proxy_getcaps (encoder, daala_supported_caps, - filter); -} - -static gboolean -daala_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (benc); - GstVideoInfo *info = &state->info; - - daala_info_clear (&enc->info); - daala_info_init (&enc->info); - enc->info.pic_width = GST_VIDEO_INFO_WIDTH (info); - enc->info.pic_height = GST_VIDEO_INFO_HEIGHT (info); - switch (GST_VIDEO_INFO_FORMAT (info)) { - case GST_VIDEO_FORMAT_I420: - enc->info.nplanes = 3; - enc->info.plane_info[0].xdec = 0; - enc->info.plane_info[0].ydec = 0; - enc->info.plane_info[1].xdec = 1; - enc->info.plane_info[1].ydec = 1; - enc->info.plane_info[2].xdec = 1; - enc->info.plane_info[2].ydec = 1; - break; - case GST_VIDEO_FORMAT_Y444: - enc->info.nplanes = 3; - enc->info.plane_info[0].xdec = 0; - enc->info.plane_info[0].ydec = 0; - enc->info.plane_info[1].xdec = 0; - enc->info.plane_info[1].ydec = 0; - enc->info.plane_info[2].xdec = 0; - enc->info.plane_info[2].ydec = 0; - break; - default: - g_assert_not_reached (); - } - - enc->info.timebase_numerator = GST_VIDEO_INFO_FPS_N (info); - enc->info.timebase_denominator = GST_VIDEO_INFO_FPS_D (info); - enc->info.frame_duration = 1; - enc->info.pixel_aspect_numerator = GST_VIDEO_INFO_PAR_N (info); - enc->info.pixel_aspect_denominator = GST_VIDEO_INFO_PAR_D (info); - - /* Save input state */ - if (enc->input_state) - gst_video_codec_state_unref (enc->input_state); - enc->input_state = gst_video_codec_state_ref (state); - - daala_enc_flush (benc); - enc->initialised = TRUE; - - return TRUE; -} - -/* this function does a straight granulepos -> timestamp conversion */ -static GstClockTime -granulepos_to_timestamp (GstDaalaEnc * enc, ogg_int64_t granulepos) -{ - guint64 iframe, pframe; - int shift = enc->info.keyframe_granule_shift; - - if (granulepos < 0) - return GST_CLOCK_TIME_NONE; - - iframe = granulepos >> shift; - pframe = granulepos - (iframe << shift); - - /* num and den are 32 bit, so we can safely multiply with GST_SECOND */ - return gst_util_uint64_scale ((guint64) (iframe + pframe), - GST_SECOND * enc->info.timebase_denominator, - enc->info.timebase_numerator); -} - -static GstFlowReturn -daala_enc_pre_push (GstVideoEncoder * benc, GstVideoCodecFrame * frame) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (benc); - guint64 pfn; - - /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its - * time representation */ - /* granulepos from sync frame */ - pfn = frame->presentation_frame_number - frame->distance_from_sync; - /* correct to correspond to linear running time */ - pfn -= enc->pfn_offset; - pfn += enc->granulepos_offset + 1; - /* granulepos */ - GST_BUFFER_OFFSET_END (frame->output_buffer) = - (pfn << enc->info.keyframe_granule_shift) + frame->distance_from_sync; - GST_BUFFER_OFFSET (frame->output_buffer) = granulepos_to_timestamp (enc, - GST_BUFFER_OFFSET_END (frame->output_buffer)); - - return GST_FLOW_OK; -} - -static GstFlowReturn -daala_push_packet (GstDaalaEnc * enc, ogg_packet * packet) -{ - GstVideoEncoder *benc; - GstFlowReturn ret; - GstVideoCodecFrame *frame; - - benc = GST_VIDEO_ENCODER (enc); - - frame = gst_video_encoder_get_oldest_frame (benc); - if (gst_video_encoder_allocate_output_frame (benc, frame, - packet->bytes) != GST_FLOW_OK) { - GST_WARNING_OBJECT (enc, "Could not allocate buffer"); - gst_video_codec_frame_unref (frame); - ret = GST_FLOW_ERROR; - goto done; - } - - if (packet->bytes > 0) - gst_buffer_fill (frame->output_buffer, 0, packet->packet, packet->bytes); - - /* the second most significant bit of the first data byte is cleared - * for keyframes */ - if (packet->bytes > 0 && (packet->packet[0] & 0x40) == 0) { - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); - } else { - GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame); - } - enc->packetno++; - - ret = gst_video_encoder_finish_frame (benc, frame); - -done: - return ret; -} - -static GstCaps * -daala_set_header_on_caps (GstCaps * caps, GList * buffers) -{ - GstStructure *structure; - GValue array = { 0 }; - GValue value = { 0 }; - GstBuffer *buffer; - GList *walk; - - caps = gst_caps_make_writable (caps); - structure = gst_caps_get_structure (caps, 0); - - /* put copies of the buffers in a fixed list */ - g_value_init (&array, GST_TYPE_ARRAY); - - for (walk = buffers; walk; walk = walk->next) { - buffer = walk->data; - g_value_init (&value, GST_TYPE_BUFFER); - gst_value_set_buffer (&value, buffer); - gst_value_array_append_value (&array, &value); - g_value_unset (&value); - } - - gst_structure_take_value (structure, "streamheader", &array); - - return caps; -} - -static void -daala_enc_init_buffer (GstDaalaEnc * enc, od_img * buf, GstVideoFrame * frame) -{ - guint i; - - buf->nplanes = 3; - buf->width = GST_VIDEO_FRAME_WIDTH (frame); - buf->height = GST_VIDEO_FRAME_HEIGHT (frame); - - for (i = 0; i < 3; i++) { - buf->planes[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i); - buf->planes[i].xdec = enc->info.plane_info[i].xdec; - buf->planes[i].ydec = enc->info.plane_info[i].ydec; - buf->planes[i].xstride = 1; - buf->planes[i].ystride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i); - } -} - -static void -daala_enc_reset_ts (GstDaalaEnc * enc, GstClockTime running_time, gint pfn) -{ - enc->granulepos_offset = - gst_util_uint64_scale (running_time, enc->input_state->info.fps_n, - GST_SECOND * enc->input_state->info.fps_d); - enc->timestamp_offset = running_time; - enc->pfn_offset = pfn; -} - -static GstBuffer * -daala_enc_buffer_from_header_packet (GstDaalaEnc * enc, ogg_packet * packet) -{ - GstBuffer *outbuf; - - outbuf = - gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (enc), - packet->bytes); - gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes); - GST_BUFFER_OFFSET (outbuf) = 0; - GST_BUFFER_OFFSET_END (outbuf) = 0; - GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE; - GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE; - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER); - - GST_DEBUG ("created header packet buffer, %u bytes", - (guint) gst_buffer_get_size (outbuf)); - return outbuf; -} - -static GstFlowReturn -daala_enc_handle_frame (GstVideoEncoder * benc, GstVideoCodecFrame * frame) -{ - GstDaalaEnc *enc; - ogg_packet op; - GstClockTime timestamp, running_time; - GstFlowReturn ret; - gboolean force_keyframe; - - enc = GST_DAALA_ENC (benc); - - /* we keep track of two timelines. - * - The timestamps from the incoming buffers, which we copy to the outgoing - * encoded buffers as-is. We need to do this as we simply forward the - * newsegment events. - * - The running_time of the buffers, which we use to construct the granulepos - * in the packets. - */ - timestamp = frame->pts; - - /* incoming buffers are clipped, so this should be positive */ - running_time = - gst_segment_to_running_time (&GST_VIDEO_ENCODER_INPUT_SEGMENT (enc), - GST_FORMAT_TIME, timestamp); - g_return_val_if_fail (running_time >= 0 || timestamp < 0, GST_FLOW_ERROR); - - GST_OBJECT_LOCK (enc); - if (enc->quant_changed) { - int quant = enc->quant; - - daala_encode_ctl (enc->encoder, OD_SET_QUANT, &quant, sizeof (int)); - enc->quant_changed = FALSE; - } - - /* see if we need to schedule a keyframe */ - force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame); - GST_OBJECT_UNLOCK (enc); - - if (enc->packetno == 0) { - /* no packets written yet, setup headers */ - GstCaps *caps; - GstBuffer *buf; - GList *buffers = NULL; - int result; - GstVideoCodecState *state; - - enc->granulepos_offset = 0; - enc->timestamp_offset = 0; - - GST_DEBUG_OBJECT (enc, "output headers"); - /* Daala streams begin with three headers; the initial header (with - most of the codec setup parameters) which is mandated by the Ogg - bitstream spec. The second header holds any comment fields. The - third header holds the bitstream codebook. We merely need to - make the headers, then pass them to libdaala one at a time; - libdaala handles the additional Ogg bitstream constraints */ - - /* create the remaining daala headers */ - daala_comment_clear (&enc->comment); - daala_comment_init (&enc->comment); - - while ((result = - daala_encode_flush_header (enc->encoder, &enc->comment, &op)) > 0) { - buf = daala_enc_buffer_from_header_packet (enc, &op); - buffers = g_list_prepend (buffers, buf); - } - if (result < 0) { - g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL); - g_list_free (buffers); - goto encoder_disabled; - } - - buffers = g_list_reverse (buffers); - - /* mark buffers and put on caps */ - caps = gst_caps_new_empty_simple ("video/x-daala"); - caps = daala_set_header_on_caps (caps, buffers); - state = gst_video_encoder_set_output_state (benc, caps, enc->input_state); - - GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, state->caps); - - gst_video_codec_state_unref (state); - - gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc)); - - gst_video_encoder_set_headers (benc, buffers); - - daala_enc_reset_ts (enc, running_time, frame->presentation_frame_number); - } - - { - od_img img; - gint res; - GstVideoFrame vframe; - - if (force_keyframe) { - /* TODO */ - } - - gst_video_frame_map (&vframe, &enc->input_state->info, frame->input_buffer, - GST_MAP_READ); - daala_enc_init_buffer (enc, &img, &vframe); - - res = daala_encode_img_in (enc->encoder, &img, 1); - gst_video_frame_unmap (&vframe); - - /* none of the failure cases can happen here */ - g_assert (res == 0); - - ret = GST_FLOW_OK; - while (daala_encode_packet_out (enc->encoder, 0, &op)) { - ret = daala_push_packet (enc, &op); - if (ret != GST_FLOW_OK) - goto beach; - } - } - -beach: - gst_video_codec_frame_unref (frame); - return ret; - - /* ERRORS */ -encoder_disabled: - { - gst_video_codec_frame_unref (frame); - GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), - ("libdaala has been compiled with the encoder disabled")); - return GST_FLOW_ERROR; - } -} - -static gboolean -daala_enc_finish (GstVideoEncoder * benc) -{ - GstDaalaEnc *enc; - ogg_packet op; - - enc = GST_DAALA_ENC (benc); - - if (enc->initialised) { - /* push last packet with eos flag, should not be called */ - while (daala_encode_packet_out (enc->encoder, 1, &op)) { - daala_push_packet (enc, &op); - } - } - - return TRUE; -} - -static gboolean -daala_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query) -{ - gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); - - return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder, - query); -} - -static void -daala_enc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (object); - - switch (prop_id) { - case PROP_QUANT: - GST_OBJECT_LOCK (enc); - enc->quant = g_value_get_int (value); - enc->quant_changed = TRUE; - GST_OBJECT_UNLOCK (enc); - break; - case PROP_KEYFRAME_RATE: - GST_OBJECT_LOCK (enc); - enc->keyframe_rate = g_value_get_int (value); - enc->keyframe_rate_changed = TRUE; - GST_OBJECT_UNLOCK (enc); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -daala_enc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstDaalaEnc *enc = GST_DAALA_ENC (object); - - switch (prop_id) { - case PROP_QUANT: - GST_OBJECT_LOCK (enc); - g_value_set_int (value, enc->quant); - GST_OBJECT_UNLOCK (enc); - break; - case PROP_KEYFRAME_RATE: - GST_OBJECT_LOCK (enc); - g_value_set_int (value, enc->keyframe_rate); - GST_OBJECT_UNLOCK (enc); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -gboolean -gst_daala_enc_register (GstPlugin * plugin) -{ - return gst_element_register (plugin, "daalaenc", - GST_RANK_PRIMARY, GST_TYPE_DAALA_ENC); -} diff --git a/ext/daala/gstdaalaenc.h b/ext/daala/gstdaalaenc.h deleted file mode 100644 index 53e9114..0000000 --- a/ext/daala/gstdaalaenc.h +++ /dev/null @@ -1,88 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * Copyright (c) 2012 Collabora Ltd. - * Author : Edward Hervey - * Author : Mark Nauwelaerts - * Copyright (c) 2013 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_DAALAENC_H__ -#define __GST_DAALAENC_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_DAALA_ENC \ - (gst_daala_enc_get_type()) -#define GST_DAALA_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DAALA_ENC,GstDaalaEnc)) -#define GST_DAALA_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DAALA_ENC,GstDaalaEncClass)) -#define GST_IS_DAALA_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DAALA_ENC)) -#define GST_IS_DAALA_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DAALA_ENC)) - -typedef struct _GstDaalaEnc GstDaalaEnc; -typedef struct _GstDaalaEncClass GstDaalaEncClass; - -/** - * GstDaalaEnc: - * - * Opaque data structure. - */ -struct _GstDaalaEnc -{ - GstVideoEncoder element; - - ogg_stream_state vo; - - daala_enc_ctx *encoder; - daala_info info; - daala_comment comment; - gboolean initialised; - - guint packetno; - guint64 bytes_out; - guint64 granulepos_offset; - guint64 timestamp_offset; - guint64 pfn_offset; - - int quant; - int keyframe_rate; - gboolean quant_changed; - gboolean keyframe_rate_changed; - - GstVideoCodecState *input_state; -}; - -struct _GstDaalaEncClass -{ - GstVideoEncoderClass parent_class; -}; - -GType gst_daala_enc_get_type (void); -gboolean gst_daala_enc_register (GstPlugin * plugin); - -G_END_DECLS - -#endif /* __GST_DAALAENC_H__ */ - diff --git a/ext/meson.build b/ext/meson.build index 0e08f51..02d3331 100644 --- a/ext/meson.build +++ b/ext/meson.build @@ -5,7 +5,6 @@ subdir('bz2') subdir('chromaprint') subdir('closedcaption') subdir('curl') -#subdir('daala') subdir('dash') subdir('dc1394') subdir('directfb') -- 2.7.4