--- a/gst_plugins_good/bwins/libgstalawu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alaw_dec_get_type @ 2 NONAME
- gst_alaw_enc_get_type @ 3 NONAME
-
--- a/gst_plugins_good/bwins/libgstalphacoloru.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alpha_color_get_type @ 2 NONAME
-
--- a/gst_plugins_good/bwins/libgstalphau.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alpha_get_type @ 2 NONAME
-
--- a/gst_plugins_good/bwins/libgstaudiofxu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- asinh @ 2 NONAME
- cosh @ 3 NONAME
- gst_audio_amplify_get_type @ 4 NONAME
- gst_audio_cheb_band_get_type @ 5 NONAME
- gst_audio_cheb_limit_get_type @ 6 NONAME
- gst_audio_dynamic_get_type @ 7 NONAME
- gst_audio_echo_get_type @ 8 NONAME
- gst_audio_fir_filter_get_type @ 9 NONAME
- gst_audio_fx_base_fir_filter_get_type @ 10 NONAME
- gst_audio_fx_base_iir_filter_get_type @ 11 NONAME
- gst_audio_iir_filter_get_type @ 12 NONAME
- gst_audio_invert_get_type @ 13 NONAME
- gst_audio_karaoke_get_type @ 14 NONAME
- gst_audio_panorama_get_type @ 15 NONAME
- gst_audio_wsincband_get_type @ 16 NONAME
- gst_audio_wsinclimit_get_type @ 17 NONAME
- sinh @ 18 NONAME
-
--- a/gst_plugins_good/bwins/libgstauparseu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_au_parse_get_type @ 2 NONAME
-
--- a/gst_plugins_good/bwins/libgstautodetectu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_auto_audio_sink_get_type @ 2 NONAME
- gst_auto_video_sink_get_type @ 3 NONAME
- gst_auto_audio_src_get_type @ 4 NONAME
- gst_auto_video_src_get_type @ 5 NONAME
-
--- a/gst_plugins_good/bwins/libgstaviu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_avi_subtitle_get_type @ 2 NONAME
-
--- a/gst_plugins_good/bwins/libgstjpegU.DEF Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
-
--- a/gst_plugins_good/bwins/libgstmpegaudioparseu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_mp3parse_get_type @ 2 NONAME
- gst_xing_mux_get_type @ 3 NONAME
-
--- a/gst_plugins_good/bwins/libgstmulawu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
-
--- a/gst_plugins_good/bwins/libgstpngu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_pngenc_get_type @ 2 NONAME
-
--- a/gst_plugins_good/bwins/libgstqtdemuxu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_rtp_xqt_depay_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstalawu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alaw_dec_get_type @ 2 NONAME
- gst_alaw_enc_get_type @ 3 NONAME
-
--- a/gst_plugins_good/eabi/libgstalphacoloru.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alpha_color_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstalphau.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_alpha_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstaudiofxu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_audio_amplify_get_type @ 2 NONAME
- gst_audio_cheb_band_get_type @ 3 NONAME
- gst_audio_cheb_limit_get_type @ 4 NONAME
- gst_audio_dynamic_get_type @ 5 NONAME
- gst_audio_echo_get_type @ 6 NONAME
- gst_audio_fir_filter_get_type @ 7 NONAME
- gst_audio_fx_base_fir_filter_get_type @ 8 NONAME
- gst_audio_fx_base_iir_filter_get_type @ 9 NONAME
- gst_audio_iir_filter_get_type @ 10 NONAME
- gst_audio_invert_get_type @ 11 NONAME
- gst_audio_karaoke_get_type @ 12 NONAME
- gst_audio_panorama_get_type @ 13 NONAME
- gst_audio_wsincband_get_type @ 14 NONAME
- gst_audio_wsinclimit_get_type @ 15 NONAME
-
--- a/gst_plugins_good/eabi/libgstauparseu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_au_parse_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstautodetectu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_auto_audio_sink_get_type @ 2 NONAME
- gst_auto_video_sink_get_type @ 3 NONAME
- gst_auto_audio_src_get_type @ 4 NONAME
- gst_auto_video_src_get_type @ 5 NONAME
-
--- a/gst_plugins_good/eabi/libgstaviu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_avi_subtitle_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstjpegU.DEF Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
-
--- a/gst_plugins_good/eabi/libgstmpegaudioparseu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_mp3parse_get_type @ 2 NONAME
- gst_xing_mux_get_type @ 3 NONAME
-
--- a/gst_plugins_good/eabi/libgstmulawu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
-
--- a/gst_plugins_good/eabi/libgstpngu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_pngenc_get_type @ 2 NONAME
-
--- a/gst_plugins_good/eabi/libgstqtdemuxu.def Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-EXPORTS
- _GST_PLUGIN_DESC @ 1 NONAME
- gst_rtp_xqt_depay_get_type @ 2 NONAME
-
--- a/gst_plugins_good/ext/jpeg/README Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-The Smoke Codec
----------------
-
-This is a very simple compression algorithm I was toying with when doing a
-Java based player. Decoding a JPEG in Java has acceptable speed so this codec
-tries to exploit that feature. The algorithm first compares the last and the
-new image and finds all 16x16 blocks that have a squared difference bigger than
-a configurable threshold. Then all these blocks are compressed into an NxM JPEG.
-The quality of the JPEG is inversely proportional to the number of blocks, this
-way, the picture quality degrades with heavy motion scenes but the bitrate stays
-more or less constant.
-Decoding decompresses the JPEG and then updates the old picture with the new
-blocks.
-
-
-TODO:
-----
-- make format extensible
-- motion vectors
-- do some real bitrate control
--- a/gst_plugins_good/ext/jpeg/gstjpeg.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <gst/gst.h>
-
-#include "gstjpegdec.h"
-#include "gstjpegenc.h"
-#include "gstsmokeenc.h"
-#include "gstsmokedec.h"
-
-#if 0
-static GstStaticCaps smoke_caps = GST_STATIC_CAPS ("video/x-smoke");
-
-#define SMOKE_CAPS (gst_static_caps_get(&smoke_caps))
-static void
-smoke_type_find (GstTypeFind * tf, gpointer private)
-{
- guint8 *data = gst_type_find_peek (tf, 0, 6);
-
- if (data) {
- if (data[0] != 0x80)
- return;
- if (memcmp (&data[1], "smoke", 5) != 0)
- return;
- gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SMOKE_CAPS);
- }
-}
-#endif
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-
- if (!gst_element_register (plugin, "jpegenc", GST_RANK_NONE,
- GST_TYPE_JPEGENC))
- return FALSE;
-
- if (!gst_element_register (plugin, "jpegdec", GST_RANK_PRIMARY,
- GST_TYPE_JPEG_DEC))
- return FALSE;
-
- if (!gst_element_register (plugin, "smokeenc", GST_RANK_PRIMARY,
- GST_TYPE_SMOKEENC))
- return FALSE;
-
- if (!gst_element_register (plugin, "smokedec", GST_RANK_PRIMARY,
- GST_TYPE_SMOKEDEC))
- return FALSE;
-
-#if 0
- if (!gst_type_find_register (plugin, "video/x-smoke", GST_RANK_PRIMARY,
- smoke_type_find, NULL, SMOKE_CAPS, NULL))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "jpeg",
- "JPeg plugin library",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-#ifdef SYMBIAN
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
-#endif
--- a/gst_plugins_good/ext/jpeg/gstjpegdec.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,998 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-
-#include "gstjpegdec.h"
-#include <gst/video/video.h>
-#include "gst/gst-i18n-plugin.h"
-#include <jerror.h>
-
-static const GstElementDetails gst_jpeg_dec_details =
-GST_ELEMENT_DETAILS ("JPEG image decoder",
- "Codec/Decoder/Image",
- "Decode images from JPEG format",
- "Wim Taymans <wim.taymans@tvd.be>");
-
-#define MIN_WIDTH 16
-#define MAX_WIDTH 4096
-#define MIN_HEIGHT 16
-#define MAX_HEIGHT 4096
-
-static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
- );
-
-static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/jpeg, "
- "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
- " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
- G_STRINGIFY (MAX_HEIGHT) " ], " "framerate = (fraction) [ 0/1, MAX ]")
- );
-
-GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
-#define GST_CAT_DEFAULT jpeg_dec_debug
-
-/* These macros are adapted from videotestsrc.c
- * and/or gst-plugins/gst/games/gstvideoimage.c */
-#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
-#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
-#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
-
-#define I420_Y_OFFSET(w,h) (0)
-#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
-#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-static GstElementClass *parent_class; /* NULL */
-
-static void gst_jpeg_dec_base_init (gpointer g_class);
-static void gst_jpeg_dec_class_init (GstJpegDecClass * klass);
-static void gst_jpeg_dec_init (GstJpegDec * jpegdec);
-
-static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps);
-static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
- GstStateChange transition);
-
-GType
-gst_jpeg_dec_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo jpeg_dec_info = {
- sizeof (GstJpegDecClass),
- (GBaseInitFunc) gst_jpeg_dec_base_init,
- NULL,
- (GClassInitFunc) gst_jpeg_dec_class_init,
- NULL,
- NULL,
- sizeof (GstJpegDec),
- 0,
- (GInstanceInitFunc) gst_jpeg_dec_init,
- };
-
- type = g_type_register_static (GST_TYPE_ELEMENT, "GstJpegDec",
- &jpeg_dec_info, 0);
- }
- return type;
-}
-
-static void
-gst_jpeg_dec_finalize (GObject * object)
-{
- GstJpegDec *dec = GST_JPEG_DEC (object);
-
- jpeg_destroy_decompress (&dec->cinfo);
-
- if (dec->tempbuf)
- gst_buffer_unref (dec->tempbuf);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_jpeg_dec_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
- gst_element_class_set_details (element_class, &gst_jpeg_dec_details);
-}
-
-static void
-gst_jpeg_dec_class_init (GstJpegDecClass * klass)
-{
- GstElementClass *gstelement_class;
- GObjectClass *gobject_class;
-
- gstelement_class = (GstElementClass *) klass;
- gobject_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_jpeg_dec_finalize;
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
-
- GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
-}
-
-static gboolean
-gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
-{
-/*
- struct GstJpegDecSourceMgr *src_mgr;
- GstJpegDec *dec;
-
- src_mgr = (struct GstJpegDecSourceMgr*) &cinfo->src;
- dec = GST_JPEG_DEC (src_mgr->dec);
-*/
- GST_DEBUG ("fill_input_buffer");
-/*
- g_return_val_if_fail (dec != NULL, TRUE);
-
- src_mgr->pub.next_input_byte = GST_BUFFER_DATA (dec->tempbuf);
- src_mgr->pub.bytes_in_buffer = GST_BUFFER_SIZE (dec->tempbuf);
-*/
- return TRUE;
-}
-
-static void
-gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
-{
- GST_DEBUG ("init_source");
-}
-
-
-static void
-gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
-{
- GST_DEBUG ("skip_input_data: %ld bytes", num_bytes);
-
- if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
- cinfo->src->next_input_byte += (size_t) num_bytes;
- cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-static gboolean
-gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
-{
- GST_DEBUG ("resync_to_start");
- return TRUE;
-}
-
-static void
-gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
-{
- GST_DEBUG ("term_source");
- return;
-}
-
-METHODDEF (void)
- gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
-{
- return; /* do nothing */
-}
-
-METHODDEF (void)
- gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
-{
- /* GST_DEBUG ("emit_message: msg_level = %d", msg_level); */
- return;
-}
-
-METHODDEF (void)
- gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
-{
- struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
-
- (*cinfo->err->output_message) (cinfo);
- longjmp (err_mgr->setjmp_buffer, 1);
-}
-
-static void
-gst_jpeg_dec_init (GstJpegDec * dec)
-{
- GST_DEBUG ("initializing");
-
- /* create the sink and src pads */
- dec->sinkpad =
- gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
- "sink");
- gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
- gst_pad_set_setcaps_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpeg_dec_setcaps));
- gst_pad_set_chain_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
-
- dec->srcpad =
- gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
- gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
-
- /* setup jpeglib */
- memset (&dec->cinfo, 0, sizeof (dec->cinfo));
- memset (&dec->jerr, 0, sizeof (dec->jerr));
- dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
- dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
- dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
- dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
-
- jpeg_create_decompress (&dec->cinfo);
-
- dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
- dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
- dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
- dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
- dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
- dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
- dec->jsrc.dec = dec;
-}
-
-static inline gboolean
-is_jpeg_start_marker (const guint8 * data)
-{
- return (data[0] == 0xff && data[1] == 0xd8);
-}
-
-static inline gboolean
-is_jpeg_end_marker (const guint8 * data)
-{
- return (data[0] == 0xff && data[1] == 0xd9);
-}
-
-static gboolean
-gst_jpeg_dec_find_jpeg_header (GstJpegDec * dec)
-{
- const guint8 *data;
- guint size;
-
- data = GST_BUFFER_DATA (dec->tempbuf);
- size = GST_BUFFER_SIZE (dec->tempbuf);
-
- g_return_val_if_fail (size >= 2, FALSE);
-
- while (!is_jpeg_start_marker (data) || data[2] != 0xff) {
- const guint8 *marker;
- GstBuffer *tmp;
- guint off;
-
- marker = memchr (data + 1, 0xff, size - 1 - 2);
- if (marker == NULL) {
- off = size - 1; /* keep last byte */
- } else {
- off = marker - data;
- }
-
- tmp = gst_buffer_create_sub (dec->tempbuf, off, size - off);
- gst_buffer_unref (dec->tempbuf);
- dec->tempbuf = tmp;
-
- data = GST_BUFFER_DATA (dec->tempbuf);
- size = GST_BUFFER_SIZE (dec->tempbuf);
-
- if (size < 2)
- return FALSE; /* wait for more data */
- }
-
- return TRUE; /* got header */
-}
-
-static gboolean
-gst_jpeg_dec_ensure_header (GstJpegDec * dec)
-{
- g_return_val_if_fail (dec->tempbuf != NULL, FALSE);
-
-check_header:
-
- /* we need at least a start marker (0xff 0xd8)
- * and an end marker (0xff 0xd9) */
- if (GST_BUFFER_SIZE (dec->tempbuf) <= 4) {
- GST_DEBUG ("Not enough data");
- return FALSE; /* we need more data */
- }
-
- if (!is_jpeg_start_marker (GST_BUFFER_DATA (dec->tempbuf))) {
- GST_DEBUG ("Not a JPEG header, resyncing to header...");
- if (!gst_jpeg_dec_find_jpeg_header (dec)) {
- GST_DEBUG ("No JPEG header in current buffer");
- return FALSE; /* we need more data */
- }
- GST_DEBUG ("Found JPEG header");
- goto check_header; /* buffer might have changed */
- }
-
- return TRUE;
-}
-
-#if 0
-static gboolean
-gst_jpeg_dec_have_end_marker (GstJpegDec * dec)
-{
- guint8 *data = GST_BUFFER_DATA (dec->tempbuf);
- guint size = GST_BUFFER_SIZE (dec->tempbuf);
-
- return (size > 2 && data && is_jpeg_end_marker (data + size - 2));
-}
-#endif
-
-static inline gboolean
-gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
-{
- if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
- return TRUE;
- return FALSE;
-}
-
-/* returns image length in bytes if parsed
- * successfully, otherwise 0 */
-static guint
-gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
-{
- guint8 *start, *data, *end;
- guint size;
-
- size = GST_BUFFER_SIZE (dec->tempbuf);
- start = GST_BUFFER_DATA (dec->tempbuf);
- end = start + size;
- data = start;
-
- g_return_val_if_fail (is_jpeg_start_marker (data), 0);
-
- GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
-
- /* skip start marker */
- data += 2;
-
- while (1) {
- guint frame_len;
-
- /* enough bytes left for EOI marker? (we need 0xff 0xNN, thus end-1) */
- if (data >= end - 1) {
- GST_DEBUG ("at end of input and no EOI marker found, need more data");
- return 0;
- }
-
- if (is_jpeg_end_marker (data)) {
- GST_DEBUG ("0x%08x: end marker", data - start);
- goto found_eoi;
- }
-
- /* do we need to resync? */
- if (*data != 0xff) {
- GST_DEBUG ("Lost sync at 0x%08x, resyncing", data - start);
- /* at the very least we expect 0xff 0xNN, thus end-1 */
- while (*data != 0xff && data < end - 1)
- ++data;
- if (is_jpeg_end_marker (data)) {
- GST_DEBUG ("resynced to end marker");
- goto found_eoi;
- }
- /* we need 0xFF 0xNN 0xLL 0xLL */
- if (data >= end - 1 - 2) {
- GST_DEBUG ("at end of input, without new sync, need more data");
- return 0;
- }
- /* check if we will still be in sync if we interpret
- * this as a sync point and skip this frame */
- frame_len = GST_READ_UINT16_BE (data + 2);
- GST_DEBUG ("possible sync at 0x%08x, frame_len=%u", data - start,
- frame_len);
- if (data + 2 + frame_len >= end - 1 || data[2 + frame_len] != 0xff) {
- /* ignore and continue resyncing until we hit the end
- * of our data or find a sync point that looks okay */
- ++data;
- continue;
- }
- GST_DEBUG ("found sync at 0x%08x", data - size);
- }
- while (*data == 0xff)
- ++data;
- if (data + 2 >= end)
- return 0;
- if (*data >= 0xd0 && *data <= 0xd7)
- frame_len = 0;
- else
- frame_len = GST_READ_UINT16_BE (data + 1);
- GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", data - start - 1, *data,
- frame_len);
- /* the frame length includes the 2 bytes for the length; here we want at
- * least 2 more bytes at the end for an end marker, thus end-2 */
- if (data + 1 + frame_len >= end - 2) {
- /* theoretically we could have lost sync and not really need more
- * data, but that's just tough luck and a broken image then */
- GST_DEBUG ("at end of input and no EOI marker found, need more data");
- return 0;
- }
- if (gst_jpeg_dec_parse_tag_has_entropy_segment (*data)) {
- guint8 *d2 = data + 1 + frame_len;
- guint eseglen = 0;
-
- GST_DEBUG ("0x%08x: finding entropy segment length", data - start - 1);
- while (1) {
- if (d2[eseglen] == 0xff && d2[eseglen + 1] != 0x00)
- break;
- if (d2 + eseglen >= end - 1)
- return 0; /* need more data */
- ++eseglen;
- }
- frame_len += eseglen;
- GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
- frame_len);
- }
- data += 1 + frame_len;
- }
-
-found_eoi:
- /* data is assumed to point to the 0xff sync point of the
- * EOI marker (so there is one more byte after that) */
- g_assert (is_jpeg_end_marker (data));
- return ((data + 1) - start + 1);
-}
-
-/* shamelessly ripped from jpegutils.c in mjpegtools */
-static void
-add_huff_table (j_decompress_ptr dinfo,
- JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
-/* Define a Huffman table */
-{
- int nsymbols, len;
-
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
-
- /* Copy the number-of-symbols-of-each-code-length counts */
- memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
-
- /* Validate the counts. We do this here mainly so we can copy the right
- * number of symbols from the val[] array, without risking marching off
- * the end of memory. jchuff.c will do a more thorough test later.
- */
- nsymbols = 0;
- for (len = 1; len <= 16; len++)
- nsymbols += bits[len];
- if (nsymbols < 1 || nsymbols > 256)
- g_error ("jpegutils.c: add_huff_table failed badly. ");
-
- memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
-}
-
-
-
-static void
-std_huff_tables (j_decompress_ptr dinfo)
-/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
-/* IMPORTANT: these are only valid for 8-bit data precision! */
-{
- static const UINT8 bits_dc_luminance[17] =
- { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
- static const UINT8 val_dc_luminance[] =
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
-
- static const UINT8 bits_dc_chrominance[17] =
- { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
- static const UINT8 val_dc_chrominance[] =
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
-
- static const UINT8 bits_ac_luminance[17] =
- { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
- static const UINT8 val_ac_luminance[] =
- { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa
- };
-
- static const UINT8 bits_ac_chrominance[17] =
- { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
- static const UINT8 val_ac_chrominance[] =
- { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
- 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
- 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
- 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
- 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
- 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
- 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
- 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa
- };
-
- add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
- bits_dc_luminance, val_dc_luminance);
- add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
- bits_ac_luminance, val_ac_luminance);
- add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
- bits_dc_chrominance, val_dc_chrominance);
- add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
- bits_ac_chrominance, val_ac_chrominance);
-}
-
-
-
-static void
-guarantee_huff_tables (j_decompress_ptr dinfo)
-{
- if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
- (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
- (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
- (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
- GST_DEBUG ("Generating standard Huffman tables for this frame.");
- std_huff_tables (dinfo);
- }
-}
-
-static gboolean
-gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstStructure *s;
- GstJpegDec *dec;
- const GValue *framerate;
-
- dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
- s = gst_caps_get_structure (caps, 0);
-
- if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
- dec->framerate_numerator = gst_value_get_fraction_numerator (framerate);
- dec->framerate_denominator = gst_value_get_fraction_denominator (framerate);
- dec->packetized = TRUE;
- GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
- dec->framerate_numerator, dec->framerate_denominator);
- }
-
- /* do not extract width/height here. we do that in the chain
- * function on a per-frame basis (including the line[] array
- * setup) */
-
- /* But we can take the framerate values and set them on the src pad */
-
- return TRUE;
-}
-
-static void
-gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
- guchar * last[3], guint width, guint height, gint r_v)
-{
-#ifdef SYMBIAN
- static guchar y[16][MAX_WIDTH];
- static guchar u[8][MAX_WIDTH / 2];
- static guchar v[8][MAX_WIDTH / 2];
- static guchar *y_rows[16] = { y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7],
- y[8], y[9], y[10], y[11], y[12], y[13], y[14], y[15]
- };
- static guchar *u_rows[8] = { u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7] };
- static guchar *v_rows[8] = { v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] };
- static guchar **scanarray[3] = { y_rows, u_rows, v_rows };
-#else // SYMBIAN
- guchar y[16][MAX_WIDTH];
- guchar u[8][MAX_WIDTH / 2];
- guchar v[8][MAX_WIDTH / 2];
- guchar *y_rows[16] = { y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7],
- y[8], y[9], y[10], y[11], y[12], y[13], y[14], y[15]
- };
- guchar *u_rows[8] = { u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7] };
- guchar *v_rows[8] = { v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] };
- guchar **scanarray[3] = { y_rows, u_rows, v_rows };
-#endif // SYMBIAN
- gint i, j, k;
-
- GST_DEBUG_OBJECT (dec,
- "unadvantageous width, taking slow route involving memcpy");
-
- for (i = 0; i < height; i += r_v * DCTSIZE) {
- jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
- for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
- memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width));
- if (base[0] < last[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- if (r_v == 2) {
- memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width));
- if (base[0] < last[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- }
- memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
- memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
- if (r_v == 2 || (k & 1) != 0) {
- if (base[1] < last[1] && base[2] < last[2]) {
- base[1] += I420_U_ROWSTRIDE (width);
- base[2] += I420_V_ROWSTRIDE (width);
- }
- }
- }
- }
-}
-
-static void
-gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3],
- guchar * last[3], guint width, guint height, gint r_v)
-{
- guchar **line[3]; /* the jpeg line buffer */
- gint i, j, k;
-
- line[0] = g_new0 (guchar *, (r_v * DCTSIZE));
- line[1] = g_new0 (guchar *, (r_v * DCTSIZE));
- line[2] = g_new0 (guchar *, (r_v * DCTSIZE));
-
- /* let jpeglib decode directly into our final buffer */
- GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
- for (i = 0; i < height; i += r_v * DCTSIZE) {
- for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
- line[0][j] = base[0];
- if (base[0] < last[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- if (r_v == 2) {
- line[0][j + 1] = base[0];
- if (base[0] < last[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- }
- line[1][k] = base[1];
- line[2][k] = base[2];
- if (r_v == 2 || (k & 1) != 0) {
- if (base[1] < last[1] && base[2] < last[2]) {
- base[1] += I420_U_ROWSTRIDE (width);
- base[2] += I420_V_ROWSTRIDE (width);
- }
- }
- }
- jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE);
- }
-
- g_free (line[0]);
- g_free (line[1]);
- g_free (line[2]);
-}
-
-
-static GstFlowReturn
-gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
-{
- GstFlowReturn ret;
- GstJpegDec *dec;
- GstBuffer *outbuf;
- gulong size;
- guchar *data, *outdata;
- guchar *base[3], *last[3];
- guint img_len;
- gint width, height;
- gint r_h, r_v;
- gint i;
- guint code;
- GstClockTime timestamp, duration;
-
- dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
-
- timestamp = GST_BUFFER_TIMESTAMP (buf);
- duration = GST_BUFFER_DURATION (buf);
-
-/*
- GST_LOG_OBJECT (dec, "Received buffer: %d bytes, ts=%" GST_TIME_FORMAT
- ", dur=%" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
- GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
-*/
-
- if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
- dec->next_ts = timestamp;
- }
-
- if (dec->tempbuf) {
- dec->tempbuf = gst_buffer_join (dec->tempbuf, buf);
- } else {
- dec->tempbuf = buf;
- }
- buf = NULL;
-
- if (!gst_jpeg_dec_ensure_header (dec))
- goto need_more_data;
-
- /* If we know that each input buffer contains data
- * for a whole jpeg image (e.g. MJPEG streams), just
- * do some sanity checking instead of parsing all of
- * the jpeg data */
- if (dec->packetized) {
- img_len = GST_BUFFER_SIZE (dec->tempbuf);
- } else {
- /* Parse jpeg image to handle jpeg input that
- * is not aligned to buffer boundaries */
- img_len = gst_jpeg_dec_parse_image_data (dec);
-
- if (img_len == 0)
- goto need_more_data;
- }
-
- data = (guchar *) GST_BUFFER_DATA (dec->tempbuf);
- size = img_len;
- GST_LOG_OBJECT (dec, "image size = %u", img_len);
-
- dec->jsrc.pub.next_input_byte = data;
- dec->jsrc.pub.bytes_in_buffer = size;
-
- if (setjmp (dec->jerr.setjmp_buffer)) {
- code = dec->jerr.pub.msg_code;
-
- if (code == JERR_INPUT_EOF) {
- GST_DEBUG ("jpeg input EOF error, we probably need more data");
- goto need_more_data;
- }
- goto decode_error;
- }
-
- GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
- data[2], data[3]);
- jpeg_read_header (&dec->cinfo, TRUE);
-
- r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor;
- r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor;
-
- GST_DEBUG ("num_components=%d, comps_in_scan=%d\n",
- dec->cinfo.num_components, dec->cinfo.comps_in_scan);
- for (i = 0; i < dec->cinfo.num_components; ++i) {
- GST_DEBUG ("[%d] h_samp_factor=%d, v_samp_factor=%d\n", i,
- dec->cinfo.cur_comp_info[i]->h_samp_factor,
- dec->cinfo.cur_comp_info[i]->v_samp_factor);
- }
-
- dec->cinfo.do_fancy_upsampling = FALSE;
- dec->cinfo.do_block_smoothing = FALSE;
- dec->cinfo.out_color_space = JCS_YCbCr;
- dec->cinfo.dct_method = JDCT_IFAST;
- dec->cinfo.raw_data_out = TRUE;
- GST_LOG_OBJECT (dec, "starting decompress");
- guarantee_huff_tables (&dec->cinfo);
- jpeg_start_decompress (&dec->cinfo);
- width = dec->cinfo.output_width;
- height = dec->cinfo.output_height;
-
- if (width < MIN_WIDTH || width > MAX_WIDTH ||
- height < MIN_HEIGHT || height > MAX_HEIGHT)
- goto wrong_size;
-
- if (width != dec->caps_width || height != dec->caps_height ||
- dec->framerate_numerator != dec->caps_framerate_numerator ||
- dec->framerate_denominator != dec->caps_framerate_denominator) {
- GstCaps *caps;
-
- /* framerate == 0/1 is a still frame */
- if (dec->framerate_denominator == 0) {
- dec->framerate_numerator = 0;
- dec->framerate_denominator = 1;
- }
-
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- "framerate", GST_TYPE_FRACTION, dec->framerate_numerator,
- dec->framerate_denominator, NULL);
-
- GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
- GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d",
- dec->cinfo.max_v_samp_factor);
-
- gst_pad_use_fixed_caps (dec->srcpad);
- gst_pad_set_caps (dec->srcpad, caps);
- gst_caps_unref (caps);
-
- dec->caps_width = width;
- dec->caps_height = height;
- dec->caps_framerate_numerator = dec->framerate_numerator;
- dec->caps_framerate_denominator = dec->framerate_denominator;
- }
-
- ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
- I420_SIZE (width, height), GST_PAD_CAPS (dec->srcpad), &outbuf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
-
- outdata = GST_BUFFER_DATA (outbuf);
- GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
-
- if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
- if (GST_CLOCK_TIME_IS_VALID (duration)) {
- /* use duration from incoming buffer for outgoing buffer */
- dec->next_ts += duration;
- } else if (dec->framerate_numerator != 0) {
- duration = gst_util_uint64_scale (GST_SECOND,
- dec->framerate_denominator, dec->framerate_numerator);
- dec->next_ts += duration;
- } else {
- duration = GST_CLOCK_TIME_NONE;
- dec->next_ts = GST_CLOCK_TIME_NONE;
- }
- } else {
- duration = GST_CLOCK_TIME_NONE;
- dec->next_ts = GST_CLOCK_TIME_NONE;
- }
- GST_BUFFER_DURATION (outbuf) = duration;
-
- GST_LOG_OBJECT (dec, "width %d, height %d, buffer size %d, required size %d",
- width, height, GST_BUFFER_SIZE (outbuf), I420_SIZE (width, height));
-
- /* mind the swap, jpeglib outputs blue chroma first */
- base[0] = outdata + I420_Y_OFFSET (width, height);
- base[1] = outdata + I420_U_OFFSET (width, height);
- base[2] = outdata + I420_V_OFFSET (width, height);
-
- /* make sure we don't make jpeglib write beyond our buffer,
- * which might happen if (height % (r_v*DCTSIZE)) != 0 */
- last[0] = base[0] + (I420_Y_ROWSTRIDE (width) * (height - 1));
- last[1] =
- base[1] + (I420_U_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
- 1));
- last[2] =
- base[2] + (I420_V_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
- 1));
-
- GST_LOG_OBJECT (dec, "decompressing %u", dec->cinfo.rec_outbuf_height);
- GST_LOG_OBJECT (dec, "max_h_samp_factor=%u", dec->cinfo.max_h_samp_factor);
-
- /* For some widths jpeglib requires more horizontal padding than I420
- * provides. In those cases we need to decode into separate buffers and then
- * copy over the data into our final picture buffer, otherwise jpeglib might
- * write over the end of a line into the beginning of the next line,
- * resulting in blocky artifacts on the left side of the picture. */
- if (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0) {
- gst_jpeg_dec_decode_indirect (dec, base, last, width, height, r_v);
- } else {
- gst_jpeg_dec_decode_direct (dec, base, last, width, height, r_v);
- }
-
- GST_LOG_OBJECT (dec, "decompressing finished");
- jpeg_finish_decompress (&dec->cinfo);
-
- GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
- GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
-
- ret = gst_pad_push (dec->srcpad, outbuf);
-
-done:
- if (GST_BUFFER_SIZE (dec->tempbuf) == img_len) {
- gst_buffer_unref (dec->tempbuf);
- dec->tempbuf = NULL;
- } else {
- GstBuffer *buf = gst_buffer_create_sub (dec->tempbuf, img_len,
- GST_BUFFER_SIZE (dec->tempbuf) - img_len);
-
- gst_buffer_unref (dec->tempbuf);
- dec->tempbuf = buf;
- }
- return ret;
-
- /* special cases */
-need_more_data:
- {
- GST_LOG_OBJECT (dec, "we need more data");
- return GST_FLOW_OK;
- }
- /* ERRORS */
-wrong_size:
- {
- GST_ELEMENT_ERROR (dec, STREAM, DECODE,
- ("Picture is too small or too big (%ux%u)", width, height),
- ("Picture is too small or too big (%ux%u)", width, height));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-decode_error:
- {
- GST_ELEMENT_ERROR (dec, STREAM, DECODE,
- (_("Failed to decode JPEG image")),
- ("Error #%u: %s", code, dec->jerr.pub.jpeg_message_table[code]));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-alloc_failed:
- {
- const gchar *reason;
-
- reason = gst_flow_get_name (ret);
-
- GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
- if (GST_FLOW_IS_FATAL (ret)) {
- GST_ELEMENT_ERROR (dec, STREAM, DECODE,
- ("Buffer allocation failed, reason: %s", reason),
- ("Buffer allocation failed, reason: %s", reason));
- }
- return ret;
- }
-}
-
-static GstStateChangeReturn
-gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstJpegDec *dec;
-
- dec = GST_JPEG_DEC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- dec->framerate_numerator = 0;
- dec->framerate_denominator = 1;
- dec->caps_framerate_numerator = dec->caps_framerate_denominator = 0;
- dec->caps_width = -1;
- dec->caps_height = -1;
- dec->packetized = FALSE;
- dec->next_ts = 0;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret != GST_STATE_CHANGE_SUCCESS)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (dec->tempbuf) {
- gst_buffer_unref (dec->tempbuf);
- dec->tempbuf = NULL;
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
--- a/gst_plugins_good/ext/jpeg/gstjpegdec.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_JPEG_DEC_H__
-#define __GST_JPEG_DEC_H__
-
-
-#include <setjmp.h>
-#include <gst/gstelement.h>
-
-/* this is a hack hack hack to get around jpeglib header bugs... */
-#ifdef HAVE_STDLIB_H
-# undef HAVE_STDLIB_H
-#endif
-#include <jpeglib.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_JPEG_DEC \
- (gst_jpeg_dec_get_type())
-#define GST_JPEG_DEC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_JPEG_DEC,GstJpegDec))
-#define GST_JPEG_DEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_JPEG_DEC,GstJpegDecClass))
-#define GST_IS_JPEG_DEC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_JPEG_DEC))
-#define GST_IS_JPEG_DEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_JPEG_DEC))
-
-typedef struct _GstJpegDec GstJpegDec;
-typedef struct _GstJpegDecClass GstJpegDecClass;
-
-struct GstJpegDecErrorMgr {
- struct jpeg_error_mgr pub; /* public fields */
- jmp_buf setjmp_buffer;
-};
-
-struct GstJpegDecSourceMgr {
- struct jpeg_source_mgr pub; /* public fields */
- GstJpegDec *dec;
-};
-
-/* Can't use GstBaseTransform, because GstBaseTransform
- * doesn't handle the N buffers in, 1 buffer out case,
- * but only the 1-in 1-out case */
-struct _GstJpegDec {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad;
- GstPad *srcpad;
-
- GstBuffer *tempbuf;
-
- /* TRUE if each input buffer contains a whole jpeg image */
- gboolean packetized;
-
- /* the (expected) timestamp of the next frame */
- guint64 next_ts;
-
- /* video state */
- gint framerate_numerator;
- gint framerate_denominator;
-
- /* negotiated state */
- gint caps_framerate_numerator;
- gint caps_framerate_denominator;
- gint caps_width;
- gint caps_height;
-
- struct jpeg_decompress_struct cinfo;
- struct GstJpegDecErrorMgr jerr;
- struct GstJpegDecSourceMgr jsrc;
-};
-
-struct _GstJpegDecClass {
- GstElementClass parent_class;
-};
-
-GType gst_jpeg_dec_get_type(void);
-
-
-G_END_DECLS
-
-
-#endif /* __GST_JPEG_DEC_H__ */
--- a/gst_plugins_good/ext/jpeg/gstjpegenc.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,565 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-
-#include "gstjpegenc.h"
-#include <gst/video/video.h>
-
-/* elementfactory information */
-static const GstElementDetails gst_jpegenc_details =
-GST_ELEMENT_DETAILS ("JPEG image encoder",
- "Codec/Encoder/Image",
- "Encode images in JPEG format",
- "Wim Taymans <wim.taymans@tvd.be>");
-
-GST_DEBUG_CATEGORY (jpegenc_debug);
-#define GST_CAT_DEFAULT jpegenc_debug
-
-#define JPEG_DEFAULT_QUALITY 85
-
-/* These macros are adapted from videotestsrc.c
- * and/or gst-plugins/gst/games/gstvideoimage.c */
-
-/* I420 */
-#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
-#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
-#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
-
-#define I420_Y_OFFSET(w,h) (0)
-#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
-#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-/* JpegEnc signals and args */
-enum
-{
- FRAME_ENCODED,
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- ARG_QUALITY,
- ARG_SMOOTHING
- /* FILL ME */
-};
-
-static void gst_jpegenc_base_init (gpointer g_class);
-static void gst_jpegenc_class_init (GstJpegEnc * klass);
-static void gst_jpegenc_init (GstJpegEnc * jpegenc);
-static void gst_jpegenc_finalize (GObject * object);
-
-static GstFlowReturn gst_jpegenc_chain (GstPad * pad, GstBuffer * buf);
-static gboolean gst_jpegenc_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_jpegenc_getcaps (GstPad * pad);
-
-static void gst_jpegenc_resync (GstJpegEnc * jpegenc);
-static void gst_jpegenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_jpegenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_jpegenc_change_state (GstElement * element,
- GstStateChange transition);
-
-
-static GstElementClass *parent_class = NULL;
-static guint gst_jpegenc_signals[LAST_SIGNAL] = { 0 };
-
-GType
-gst_jpegenc_get_type (void)
-{
- static GType jpegenc_type = 0;
-
- if (!jpegenc_type) {
- static const GTypeInfo jpegenc_info = {
- sizeof (GstJpegEnc),
- (GBaseInitFunc) gst_jpegenc_base_init,
- NULL,
- (GClassInitFunc) gst_jpegenc_class_init,
- NULL,
- NULL,
- sizeof (GstJpegEnc),
- 0,
- (GInstanceInitFunc) gst_jpegenc_init,
- };
-
- jpegenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstJpegEnc", &jpegenc_info,
- 0);
- }
- return jpegenc_type;
-}
-
-static GstStaticPadTemplate gst_jpegenc_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
- );
-
-static GstStaticPadTemplate gst_jpegenc_src_pad_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/jpeg, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0/1, MAX ]")
- );
-
-static void
-gst_jpegenc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_jpegenc_sink_pad_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_jpegenc_src_pad_template));
- gst_element_class_set_details (element_class, &gst_jpegenc_details);
-}
-
-static void
-gst_jpegenc_class_init (GstJpegEnc * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gst_jpegenc_signals[FRAME_ENCODED] =
- g_signal_new ("frame-encoded", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstJpegEncClass, frame_encoded), NULL,
- NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- gobject_class->set_property = gst_jpegenc_set_property;
- gobject_class->get_property = gst_jpegenc_get_property;
-
-
- g_object_class_install_property (gobject_class, ARG_QUALITY,
- g_param_spec_int ("quality", "Quality", "Quality of encoding",
- 0, 100, JPEG_DEFAULT_QUALITY, G_PARAM_READWRITE));
-#if 0
- /* disabled, since it doesn't seem to work */
- g_object_class_install_property (gobject_class, ARG_SMOOTHING,
- g_param_spec_int ("smoothing", "Smoothing", "Smoothing factor",
- 0, 100, 0, G_PARAM_READWRITE));
-#endif
-
- gstelement_class->change_state = gst_jpegenc_change_state;
-
- gobject_class->finalize = gst_jpegenc_finalize;
-
- GST_DEBUG_CATEGORY_INIT (jpegenc_debug, "jpegenc", 0,
- "JPEG encoding element");
-}
-
-static void
-gst_jpegenc_init_destination (j_compress_ptr cinfo)
-{
- GST_DEBUG ("gst_jpegenc_chain: init_destination");
-}
-
-static gboolean
-gst_jpegenc_flush_destination (j_compress_ptr cinfo)
-{
- GST_DEBUG ("gst_jpegenc_chain: flush_destination: buffer too small !!!");
- return TRUE;
-}
-
-static void
-gst_jpegenc_term_destination (j_compress_ptr cinfo)
-{
- GST_DEBUG ("gst_jpegenc_chain: term_source");
-}
-
-static void
-gst_jpegenc_init (GstJpegEnc * jpegenc)
-{
- /* create the sink and src pads */
- jpegenc->sinkpad =
- gst_pad_new_from_static_template (&gst_jpegenc_sink_pad_template, "sink");
- gst_pad_set_chain_function (jpegenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpegenc_chain));
- gst_pad_set_getcaps_function (jpegenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpegenc_getcaps));
- gst_pad_set_setcaps_function (jpegenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpegenc_setcaps));
- gst_element_add_pad (GST_ELEMENT (jpegenc), jpegenc->sinkpad);
-
- jpegenc->srcpad =
- gst_pad_new_from_static_template (&gst_jpegenc_src_pad_template, "src");
- gst_pad_set_getcaps_function (jpegenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpegenc_getcaps));
- /*gst_pad_set_setcaps_function (jpegenc->sinkpad, gst_jpegenc_setcaps); */
- gst_pad_use_fixed_caps (jpegenc->sinkpad);
- gst_element_add_pad (GST_ELEMENT (jpegenc), jpegenc->srcpad);
-
- /* reset the initial video state */
- jpegenc->width = -1;
- jpegenc->height = -1;
-
- /* setup jpeglib */
- memset (&jpegenc->cinfo, 0, sizeof (jpegenc->cinfo));
- memset (&jpegenc->jerr, 0, sizeof (jpegenc->jerr));
- jpegenc->cinfo.err = jpeg_std_error (&jpegenc->jerr);
- jpeg_create_compress (&jpegenc->cinfo);
-
- jpegenc->jdest.init_destination = gst_jpegenc_init_destination;
- jpegenc->jdest.empty_output_buffer = gst_jpegenc_flush_destination;
- jpegenc->jdest.term_destination = gst_jpegenc_term_destination;
- jpegenc->cinfo.dest = &jpegenc->jdest;
-
- jpegenc->quality = JPEG_DEFAULT_QUALITY;
- jpegenc->smoothing = 0;
-}
-
-static void
-gst_jpegenc_finalize (GObject * object)
-{
-
- GstJpegEnc *filter = GST_JPEGENC (object);
-
- jpeg_destroy_compress (&filter->cinfo);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static GstCaps *
-gst_jpegenc_getcaps (GstPad * pad)
-{
- GstJpegEnc *jpegenc = GST_JPEGENC (gst_pad_get_parent (pad));
- GstPad *otherpad;
- GstCaps *caps;
- const char *name;
- int i;
- GstStructure *structure = NULL;
-
- /* we want to proxy properties like width, height and framerate from the
- other end of the element */
- otherpad = (pad == jpegenc->srcpad) ? jpegenc->sinkpad : jpegenc->srcpad;
- caps = gst_pad_get_allowed_caps (otherpad);
- if (pad == jpegenc->srcpad) {
- name = "image/jpeg";
- } else {
- name = "video/x-raw-yuv";
- }
- for (i = 0; i < gst_caps_get_size (caps); i++) {
- structure = gst_caps_get_structure (caps, i);
-
- gst_structure_set_name (structure, name);
- gst_structure_remove_field (structure, "format");
- /* ... but for the sink pad, we only do I420 anyway, so add that */
- if (pad == jpegenc->sinkpad) {
- gst_structure_set (structure, "format", GST_TYPE_FOURCC,
- GST_STR_FOURCC ("I420"), NULL);
- }
- }
- gst_object_unref (jpegenc);
-
- return caps;
-}
-
-static gboolean
-gst_jpegenc_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstJpegEnc *jpegenc = GST_JPEGENC (gst_pad_get_parent (pad));
- GstStructure *structure;
- GstCaps *othercaps;
- GstPad *otherpad;
- gboolean ret;
- const GValue *framerate;
-
- otherpad = (pad == jpegenc->srcpad) ? jpegenc->sinkpad : jpegenc->srcpad;
-
- structure = gst_caps_get_structure (caps, 0);
- framerate = gst_structure_get_value (structure, "framerate");
- gst_structure_get_int (structure, "width", &jpegenc->width);
- gst_structure_get_int (structure, "height", &jpegenc->height);
-
- othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
- if (framerate) {
- gst_caps_set_simple (othercaps,
- "width", G_TYPE_INT, jpegenc->width,
- "height", G_TYPE_INT, jpegenc->height,
- "framerate", GST_TYPE_FRACTION,
- gst_value_get_fraction_numerator (framerate),
- gst_value_get_fraction_denominator (framerate), NULL);
- } else {
- gst_caps_set_simple (othercaps,
- "width", G_TYPE_INT, jpegenc->width,
- "height", G_TYPE_INT, jpegenc->height, NULL);
- }
-
- ret = gst_pad_set_caps (jpegenc->srcpad, othercaps);
- gst_caps_unref (othercaps);
-
- if (GST_PAD_LINK_SUCCESSFUL (ret)) {
- gst_jpegenc_resync (jpegenc);
- }
-
- gst_object_unref (jpegenc);
-
- return ret;
-}
-
-static void
-gst_jpegenc_resync (GstJpegEnc * jpegenc)
-{
- gint width, height;
-
- GST_DEBUG_OBJECT (jpegenc, "resync");
-
- jpegenc->cinfo.image_width = width = jpegenc->width;
- jpegenc->cinfo.image_height = height = jpegenc->height;
- jpegenc->cinfo.input_components = 3;
-
- GST_DEBUG_OBJECT (jpegenc, "width %d, height %d", width, height);
-
- jpeg_set_defaults (&jpegenc->cinfo);
- jpegenc->cinfo.dct_method = JDCT_FASTEST;
- /*jpegenc->cinfo.dct_method = JDCT_DEFAULT; */
- /*jpegenc->cinfo.smoothing_factor = jpegenc->smoothing; */
- jpeg_set_quality (&jpegenc->cinfo, jpegenc->quality, TRUE);
-
-#if 0
- switch (jpegenc->format) {
- case GST_COLORSPACE_RGB24:
- jpegenc->bufsize = jpegenc->width * jpegenc->height * 3;
- GST_DEBUG ("gst_jpegenc_resync: setting format to RGB24");
- jpegenc->cinfo.in_color_space = JCS_RGB;
- jpegenc->cinfo.raw_data_in = FALSE;
- break;
- case GST_COLORSPACE_YUV420P:
-#endif
- jpegenc->bufsize = I420_SIZE (jpegenc->width, jpegenc->height);
- jpegenc->cinfo.raw_data_in = TRUE;
- jpegenc->cinfo.in_color_space = JCS_YCbCr;
- GST_DEBUG_OBJECT (jpegenc, "setting format to YUV420P");
- jpegenc->cinfo.comp_info[0].h_samp_factor = 2;
- jpegenc->cinfo.comp_info[0].v_samp_factor = 2;
- jpegenc->cinfo.comp_info[1].h_samp_factor = 1;
- jpegenc->cinfo.comp_info[1].v_samp_factor = 1;
- jpegenc->cinfo.comp_info[2].h_samp_factor = 1;
- jpegenc->cinfo.comp_info[2].v_samp_factor = 1;
-
- if (height != -1) {
- jpegenc->line[0] =
- g_realloc (jpegenc->line[0], height * sizeof (char *));
- jpegenc->line[1] =
- g_realloc (jpegenc->line[1], height * sizeof (char *) / 2);
- jpegenc->line[2] =
- g_realloc (jpegenc->line[2], height * sizeof (char *) / 2);
- }
-
- GST_DEBUG_OBJECT (jpegenc, "setting format done");
-#if 0
- break;
- default:
- printf ("gst_jpegenc_resync: unsupported colorspace, using RGB\n");
- jpegenc->bufsize = jpegenc->width * jpegenc->height * 3;
- jpegenc->cinfo.in_color_space = JCS_RGB;
- break;
- }
-#endif
-
- jpeg_suppress_tables (&jpegenc->cinfo, TRUE);
- //jpeg_suppress_tables(&jpegenc->cinfo, FALSE);
-
- jpegenc->buffer = NULL;
- GST_DEBUG_OBJECT (jpegenc, "resync done");
-}
-
-static GstFlowReturn
-gst_jpegenc_chain (GstPad * pad, GstBuffer * buf)
-{
- GstFlowReturn ret;
- GstJpegEnc *jpegenc;
- guchar *data;
- gulong size;
- GstBuffer *outbuf;
- guint height, width;
- guchar *base[3], *end[3];
- gint i, j, k;
-
- jpegenc = GST_JPEGENC (GST_OBJECT_PARENT (pad));
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- GST_DEBUG_OBJECT (jpegenc, "got buffer of %u bytes", size);
-
- ret =
- gst_pad_alloc_buffer_and_set_caps (jpegenc->srcpad,
- GST_BUFFER_OFFSET_NONE, jpegenc->bufsize, GST_PAD_CAPS (jpegenc->srcpad),
- &outbuf);
-
- if (ret != GST_FLOW_OK)
- goto done;
-
- gst_buffer_stamp (outbuf, buf);
-
- width = jpegenc->width;
- height = jpegenc->height;
-
- base[0] = data + I420_Y_OFFSET (width, height);
- base[1] = data + I420_U_OFFSET (width, height);
- base[2] = data + I420_V_OFFSET (width, height);
-
- end[0] = base[0] + height * I420_Y_ROWSTRIDE (width);
- end[1] = base[1] + (height / 2) * I420_U_ROWSTRIDE (width);
- end[2] = base[2] + (height / 2) * I420_V_ROWSTRIDE (width);
-
- jpegenc->jdest.next_output_byte = GST_BUFFER_DATA (outbuf);
- jpegenc->jdest.free_in_buffer = GST_BUFFER_SIZE (outbuf);
-
- jpegenc->cinfo.smoothing_factor = jpegenc->smoothing;
- jpeg_set_quality (&jpegenc->cinfo, jpegenc->quality, TRUE);
- jpeg_start_compress (&jpegenc->cinfo, TRUE);
-
- GST_DEBUG_OBJECT (jpegenc, "compressing");
-
- for (i = 0; i < height; i += 2 * DCTSIZE) {
- /*g_print ("next scanline: %d\n", jpegenc->cinfo.next_scanline); */
- for (j = 0, k = 0; j < (2 * DCTSIZE); j += 2, k++) {
- jpegenc->line[0][j] = base[0];
- if (base[0] + I420_Y_ROWSTRIDE (width) < end[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- jpegenc->line[0][j + 1] = base[0];
- if (base[0] + I420_Y_ROWSTRIDE (width) < end[0])
- base[0] += I420_Y_ROWSTRIDE (width);
- jpegenc->line[1][k] = base[1];
- if (base[1] + I420_U_ROWSTRIDE (width) < end[1])
- base[1] += I420_U_ROWSTRIDE (width);
- jpegenc->line[2][k] = base[2];
- if (base[2] + I420_V_ROWSTRIDE (width) < end[2])
- base[2] += I420_V_ROWSTRIDE (width);
- }
- jpeg_write_raw_data (&jpegenc->cinfo, jpegenc->line, 2 * DCTSIZE);
- }
-
- jpeg_finish_compress (&jpegenc->cinfo);
- GST_DEBUG_OBJECT (jpegenc, "compressing done");
-
- GST_BUFFER_SIZE (outbuf) =
- GST_ROUND_UP_4 (jpegenc->bufsize - jpegenc->jdest.free_in_buffer);
-
- g_signal_emit (G_OBJECT (jpegenc), gst_jpegenc_signals[FRAME_ENCODED], 0);
-
- ret = gst_pad_push (jpegenc->srcpad, outbuf);
-
-done:
- gst_buffer_unref (buf);
-
- return ret;
-}
-
-static void
-gst_jpegenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstJpegEnc *jpegenc = GST_JPEGENC (object);
-
- GST_OBJECT_LOCK (jpegenc);
-
- switch (prop_id) {
- case ARG_QUALITY:
- jpegenc->quality = g_value_get_int (value);
- break;
- case ARG_SMOOTHING:
- jpegenc->smoothing = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
- GST_OBJECT_UNLOCK (jpegenc);
-}
-
-static void
-gst_jpegenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstJpegEnc *jpegenc = GST_JPEGENC (object);
-
- GST_OBJECT_LOCK (jpegenc);
-
- switch (prop_id) {
- case ARG_QUALITY:
- g_value_set_int (value, jpegenc->quality);
- break;
- case ARG_SMOOTHING:
- g_value_set_int (value, jpegenc->smoothing);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
- GST_OBJECT_UNLOCK (jpegenc);
-}
-
-static GstStateChangeReturn
-gst_jpegenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstJpegEnc *filter = GST_JPEGENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- GST_DEBUG_OBJECT (element, "setting line buffers");
- filter->line[0] = NULL;
- filter->line[1] = NULL;
- filter->line[2] = NULL;
- gst_jpegenc_resync (filter);
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- g_free (filter->line[0]);
- g_free (filter->line[1]);
- g_free (filter->line[2]);
- filter->line[0] = NULL;
- filter->line[1] = NULL;
- filter->line[2] = NULL;
- break;
- default:
- break;
- }
-
- return ret;
-}
--- a/gst_plugins_good/ext/jpeg/gstjpegenc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_JPEGENC_H__
-#define __GST_JPEGENC_H__
-
-
-#include <gst/gst.h>
-/* this is a hack hack hack to get around jpeglib header bugs... */
-#ifdef HAVE_STDLIB_H
-# undef HAVE_STDLIB_H
-#endif
-#include <jpeglib.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_JPEGENC \
- (gst_jpegenc_get_type())
-#define GST_JPEGENC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_JPEGENC,GstJpegEnc))
-#define GST_JPEGENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_JPEGENC,GstJpegEnc))
-#define GST_IS_JPEGENC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_JPEGENC))
-#define GST_IS_JPEGENC_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_JPEGENC))
-
-typedef struct _GstJpegEnc GstJpegEnc;
-typedef struct _GstJpegEncClass GstJpegEncClass;
-
-struct _GstJpegEnc {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad,*srcpad;
-
- /* video state */
- gint format;
- gint width;
- gint height;
- /* the video buffer */
- gint bufsize;
- GstBuffer *buffer;
- guint row_stride;
- /* the jpeg line buffer */
- guchar **line[3];
-
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- struct jpeg_destination_mgr jdest;
-
- int quality;
- int smoothing;
-};
-
-struct _GstJpegEncClass {
- GstElementClass parent_class;
-
- /* signals */
- void (*frame_encoded) (GstElement *element);
-};
-
-GType gst_jpegenc_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_JPEGENC_H__ */
--- a/gst_plugins_good/ext/jpeg/gstsmokedec.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-
-/*#define DEBUG_ENABLED*/
-#include "gstsmokedec.h"
-#include <gst/video/video.h>
-
-/* elementfactory information */
-static const GstElementDetails gst_smokedec_details =
-GST_ELEMENT_DETAILS ("Smoke video decoder",
- "Codec/Decoder/Video",
- "Decode video from Smoke format",
- "Wim Taymans <wim@fluendo.com>");
-
-GST_DEBUG_CATEGORY (smokedec_debug);
-#define GST_CAT_DEFAULT smokedec_debug
-
-/* SmokeDec signals and args */
-enum
-{
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0
-};
-
-static void gst_smokedec_base_init (gpointer g_class);
-static void gst_smokedec_class_init (GstSmokeDec * klass);
-static void gst_smokedec_init (GstSmokeDec * smokedec);
-
-static GstFlowReturn gst_smokedec_chain (GstPad * pad, GstBuffer * buf);
-
-static GstElementClass *parent_class = NULL;
-
-/*static guint gst_smokedec_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_smokedec_get_type (void)
-{
- static GType smokedec_type = 0;
-
- if (!smokedec_type) {
- static const GTypeInfo smokedec_info = {
- sizeof (GstSmokeDecClass),
- gst_smokedec_base_init,
- NULL,
- (GClassInitFunc) gst_smokedec_class_init,
- NULL,
- NULL,
- sizeof (GstSmokeDec),
- 0,
- (GInstanceInitFunc) gst_smokedec_init,
- };
-
- smokedec_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstSmokeDec", &smokedec_info,
- 0);
- }
- return smokedec_type;
-}
-
-static GstStaticPadTemplate gst_smokedec_src_pad_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
- );
-
-static GstStaticPadTemplate gst_smokedec_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-smoke, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0/1, MAX ]")
- );
-
-static void
-gst_smokedec_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_smokedec_src_pad_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_smokedec_sink_pad_template));
- gst_element_class_set_details (element_class, &gst_smokedec_details);
-}
-
-static void
-gst_smokedec_class_init (GstSmokeDec * klass)
-{
- GstElementClass *gstelement_class;
-
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- GST_DEBUG_CATEGORY_INIT (smokedec_debug, "smokedec", 0, "Smoke decoder");
-}
-
-static void
-gst_smokedec_init (GstSmokeDec * smokedec)
-{
- GST_DEBUG_OBJECT (smokedec, "gst_smokedec_init: initializing");
- /* create the sink and src pads */
-
- smokedec->sinkpad =
- gst_pad_new_from_static_template (&gst_smokedec_sink_pad_template,
- "sink");
- gst_pad_set_chain_function (smokedec->sinkpad, gst_smokedec_chain);
- gst_element_add_pad (GST_ELEMENT (smokedec), smokedec->sinkpad);
-
- smokedec->srcpad =
- gst_pad_new_from_static_template (&gst_smokedec_src_pad_template, "src");
- gst_pad_use_fixed_caps (smokedec->srcpad);
- gst_element_add_pad (GST_ELEMENT (smokedec), smokedec->srcpad);
-
- /* reset the initial video state */
- smokedec->format = -1;
- smokedec->width = -1;
- smokedec->height = -1;
- smokedec->fps_num = -1;
- smokedec->fps_denom = -1;
- smokedec->next_time = 0;
-
- smokecodec_decode_new (&smokedec->info);
-}
-
-static GstFlowReturn
-gst_smokedec_chain (GstPad * pad, GstBuffer * buf)
-{
- GstSmokeDec *smokedec;
- guint8 *data, *outdata;
- gulong size, outsize;
- GstBuffer *outbuf;
- SmokeCodecFlags flags;
- GstClockTime time;
- guint width, height;
- guint fps_num, fps_denom;
- gint smokeret;
- GstFlowReturn ret;
-
- smokedec = GST_SMOKEDEC (gst_pad_get_parent (pad));
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
- time = GST_BUFFER_TIMESTAMP (buf);
-
- GST_DEBUG_OBJECT (smokedec,
- "gst_smokedec_chain: got buffer of %ld bytes in '%s'", size,
- GST_OBJECT_NAME (smokedec));
-
- /* have the ID packet. */
- if (data[0] == SMOKECODEC_TYPE_ID) {
- smokeret = smokecodec_parse_id (smokedec->info, data, size);
- if (smokeret != SMOKECODEC_OK)
- goto header_error;
-
- ret = GST_FLOW_OK;
- goto done;
- }
-
- /* now handle data packets */
- GST_DEBUG_OBJECT (smokedec, "gst_smokedec_chain: reading header %08lx",
- *(gulong *) data);
- smokecodec_parse_header (smokedec->info, data, size, &flags, &width, &height,
- &fps_num, &fps_denom);
-
- if (smokedec->height != height || smokedec->width != width ||
- smokedec->fps_num != fps_num || smokedec->fps_denom != fps_denom) {
- GstCaps *caps;
-
- smokedec->height = height;
- smokedec->width = width;
-
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- "framerate", GST_TYPE_FRACTION, fps_num, fps_denom, NULL);
-
- gst_pad_set_caps (smokedec->srcpad, caps);
- gst_caps_unref (caps);
- }
-
-
- if (smokedec->need_keyframe) {
- if (!(flags & SMOKECODEC_KEYFRAME))
- goto keyframe_skip;
-
- smokedec->need_keyframe = FALSE;
- }
-
- outbuf = gst_buffer_new ();
- outsize = GST_BUFFER_SIZE (outbuf) = width * height + width * height / 2;
- outdata = g_malloc (outsize);
- GST_BUFFER_DATA (outbuf) = outdata;
- GST_BUFFER_MALLOCDATA (outbuf) = outdata;
-
- GST_BUFFER_DURATION (outbuf) = GST_SECOND * fps_denom / fps_num;
- GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (smokedec->srcpad));
-
- if (time == GST_CLOCK_TIME_NONE) {
- if (GST_BUFFER_OFFSET (buf) == -1) {
- time = smokedec->next_time;
- } else {
- time = GST_BUFFER_OFFSET (buf) * GST_BUFFER_DURATION (outbuf);
- }
- }
- GST_BUFFER_TIMESTAMP (outbuf) = time;
- smokedec->next_time = time + GST_BUFFER_DURATION (outbuf);
-
- smokeret = smokecodec_decode (smokedec->info, data, size, outdata);
- if (smokeret != SMOKECODEC_OK)
- goto decode_error;
-
- GST_DEBUG_OBJECT (smokedec, "gst_smokedec_chain: sending buffer");
- ret = gst_pad_push (smokedec->srcpad, outbuf);
-
-done:
- gst_buffer_unref (buf);
- gst_object_unref (smokedec);
-
- return ret;
-
- /* ERRORS */
-header_error:
- {
- GST_ELEMENT_ERROR (smokedec, STREAM, DECODE,
- (NULL), ("Could not parse smoke header, reason: %d", smokeret));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-keyframe_skip:
- {
- GST_DEBUG_OBJECT (smokedec, "dropping buffer while waiting for keyframe");
- ret = GST_FLOW_OK;
- goto done;
- }
-decode_error:
- {
- GST_ELEMENT_ERROR (smokedec, STREAM, DECODE,
- (NULL), ("Could not decode smoke frame, reason: %d", smokeret));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-}
--- a/gst_plugins_good/ext/jpeg/gstsmokedec.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_SMOKEDEC_H__
-#define __GST_SMOKEDEC_H__
-
-
-#include <gst/gst.h>
-#include "smokecodec.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SMOKEDEC \
- (gst_smokedec_get_type())
-#define GST_SMOKEDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SMOKEDEC,GstSmokeDec))
-#define GST_SMOKEDEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SMOKEDEC,GstSmokeDec))
-#define GST_IS_SMOKEDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SMOKEDEC))
-#define GST_IS_SMOKEDEC_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SMOKEDEC))
-
-typedef struct _GstSmokeDec GstSmokeDec;
-typedef struct _GstSmokeDecClass GstSmokeDecClass;
-
-struct _GstSmokeDec {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad,*srcpad;
-
- /* video state */
- gint format;
- gint width;
- gint height;
- gint fps_num;
- gint fps_denom;
- GstClockTime next_time;
-
- SmokeCodecInfo *info;
-
- gint threshold;
- gint quality;
- gint smoothing;
-
- gboolean need_keyframe;
-};
-
-struct _GstSmokeDecClass {
- GstElementClass parent_class;
-};
-
-GType gst_smokedec_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_SMOKEDEC_H__ */
--- a/gst_plugins_good/ext/jpeg/gstsmokeenc.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-
-#include "gstsmokeenc.h"
-#include <gst/video/video.h>
-
-/* elementfactory information */
-static const GstElementDetails gst_smokeenc_details =
-GST_ELEMENT_DETAILS ("Smoke video encoder",
- "Codec/Encoder/Video",
- "Encode images into the Smoke format",
- "Wim Taymans <wim@fluendo.com>");
-
-GST_DEBUG_CATEGORY (smokeenc_debug);
-#define GST_CAT_DEFAULT smokeenc_debug
-
-#define SMOKEENC_DEFAULT_MIN_QUALITY 10
-#define SMOKEENC_DEFAULT_MAX_QUALITY 85
-#define SMOKEENC_DEFAULT_THRESHOLD 3000
-#define SMOKEENC_DEFAULT_KEYFRAME 20
-
-/* SmokeEnc signals and args */
-enum
-{
- FRAME_ENCODED,
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- ARG_MIN_QUALITY,
- ARG_MAX_QUALITY,
- ARG_THRESHOLD,
- ARG_KEYFRAME
- /* FILL ME */
-};
-
-static void gst_smokeenc_base_init (gpointer g_class);
-static void gst_smokeenc_class_init (GstSmokeEnc * klass);
-static void gst_smokeenc_init (GstSmokeEnc * smokeenc);
-
-static GstFlowReturn gst_smokeenc_chain (GstPad * pad, GstBuffer * buf);
-static gboolean gst_smokeenc_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_smokeenc_getcaps (GstPad * pad);
-
-static void gst_smokeenc_resync (GstSmokeEnc * smokeenc);
-static void gst_smokeenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_smokeenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static GstElementClass *parent_class = NULL;
-
-//static guint gst_smokeenc_signals[LAST_SIGNAL] = { 0 };
-
-GType
-gst_smokeenc_get_type (void)
-{
- static GType smokeenc_type = 0;
-
- if (!smokeenc_type) {
- static const GTypeInfo smokeenc_info = {
- sizeof (GstSmokeEncClass),
- (GBaseInitFunc) gst_smokeenc_base_init,
- NULL,
- (GClassInitFunc) gst_smokeenc_class_init,
- NULL,
- NULL,
- sizeof (GstSmokeEnc),
- 0,
- (GInstanceInitFunc) gst_smokeenc_init,
- };
-
- smokeenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstSmokeEnc", &smokeenc_info,
- 0);
- }
- return smokeenc_type;
-}
-
-static GstStaticPadTemplate gst_smokeenc_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
- );
-
-static GstStaticPadTemplate gst_smokeenc_src_pad_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-smoke, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0/1, MAX ]")
- );
-
-static void
-gst_smokeenc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_smokeenc_sink_pad_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_smokeenc_src_pad_template));
- gst_element_class_set_details (element_class, &gst_smokeenc_details);
-}
-
-static void
-gst_smokeenc_class_init (GstSmokeEnc * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->set_property = gst_smokeenc_set_property;
- gobject_class->get_property = gst_smokeenc_get_property;
-
- g_object_class_install_property (gobject_class, ARG_MIN_QUALITY,
- g_param_spec_int ("qmin", "Qmin", "Minimum quality",
- 0, 100, SMOKEENC_DEFAULT_MIN_QUALITY, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, ARG_MAX_QUALITY,
- g_param_spec_int ("qmax", "Qmax", "Maximum quality",
- 0, 100, SMOKEENC_DEFAULT_MAX_QUALITY, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, ARG_THRESHOLD,
- g_param_spec_int ("threshold", "Threshold", "Motion estimation threshold",
- 0, 100000000, SMOKEENC_DEFAULT_THRESHOLD, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, ARG_KEYFRAME,
- g_param_spec_int ("keyframe", "Keyframe",
- "Insert keyframe every N frames", 1, 100000,
- SMOKEENC_DEFAULT_KEYFRAME, G_PARAM_READWRITE));
-
- GST_DEBUG_CATEGORY_INIT (smokeenc_debug, "smokeenc", 0,
- "Smoke encoding element");
-}
-
-static void
-gst_smokeenc_init (GstSmokeEnc * smokeenc)
-{
- /* create the sink and src pads */
- smokeenc->sinkpad =
- gst_pad_new_from_static_template (&gst_smokeenc_sink_pad_template,
- "sink");
- gst_pad_set_chain_function (smokeenc->sinkpad, gst_smokeenc_chain);
- gst_pad_set_getcaps_function (smokeenc->sinkpad, gst_smokeenc_getcaps);
- gst_pad_set_setcaps_function (smokeenc->sinkpad, gst_smokeenc_setcaps);
- gst_element_add_pad (GST_ELEMENT (smokeenc), smokeenc->sinkpad);
-
- smokeenc->srcpad =
- gst_pad_new_from_static_template (&gst_smokeenc_src_pad_template, "src");
- gst_pad_set_getcaps_function (smokeenc->sinkpad, gst_smokeenc_getcaps);
- gst_pad_use_fixed_caps (smokeenc->sinkpad);
- /*gst_pad_set_link_function (smokeenc->sinkpad, gst_smokeenc_link); */
- gst_element_add_pad (GST_ELEMENT (smokeenc), smokeenc->srcpad);
-
- /* reset the initial video state */
- smokeenc->width = 0;
- smokeenc->height = 0;
- smokeenc->frame = 0;
- smokeenc->need_header = TRUE;
-
- gst_smokeenc_resync (smokeenc);
-
- smokeenc->min_quality = SMOKEENC_DEFAULT_MIN_QUALITY;
- smokeenc->max_quality = SMOKEENC_DEFAULT_MAX_QUALITY;
- smokeenc->threshold = SMOKEENC_DEFAULT_THRESHOLD;
- smokeenc->keyframe = SMOKEENC_DEFAULT_KEYFRAME;
-}
-
-static GstCaps *
-gst_smokeenc_getcaps (GstPad * pad)
-{
- GstSmokeEnc *smokeenc = GST_SMOKEENC (gst_pad_get_parent (pad));
- GstPad *otherpad;
- GstCaps *caps;
- const char *name;
- int i;
- GstStructure *structure = NULL;
-
- /* we want to proxy properties like width, height and framerate from the
- other end of the element */
- otherpad = (pad == smokeenc->srcpad) ? smokeenc->sinkpad : smokeenc->srcpad;
- caps = gst_pad_get_allowed_caps (otherpad);
- if (pad == smokeenc->srcpad) {
- name = "image/x-smoke";
- } else {
- name = "video/x-raw-yuv";
- }
- for (i = 0; i < gst_caps_get_size (caps); i++) {
- structure = gst_caps_get_structure (caps, i);
-
- gst_structure_set_name (structure, name);
- gst_structure_remove_field (structure, "format");
- /* ... but for the sink pad, we only do I420 anyway, so add that */
- if (pad == smokeenc->sinkpad) {
- gst_structure_set (structure, "format", GST_TYPE_FOURCC,
- GST_STR_FOURCC ("I420"), NULL);
- }
- }
-
- gst_object_unref (smokeenc);
-
- return caps;
-}
-
-static gboolean
-gst_smokeenc_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstSmokeEnc *smokeenc = GST_SMOKEENC (gst_pad_get_parent (pad));
- GstStructure *structure;
- gboolean ret = TRUE;
- GstCaps *othercaps;
- GstPad *otherpad;
- const GValue *framerate;
-
- otherpad = (pad == smokeenc->srcpad) ? smokeenc->sinkpad : smokeenc->srcpad;
-
- structure = gst_caps_get_structure (caps, 0);
- framerate = gst_structure_get_value (structure, "framerate");
- if (framerate) {
- smokeenc->fps_num = gst_value_get_fraction_numerator (framerate);
- smokeenc->fps_denom = gst_value_get_fraction_denominator (framerate);
- } else {
- smokeenc->fps_num = 0;
- smokeenc->fps_denom = 1;
- }
-
- gst_structure_get_int (structure, "width", &smokeenc->width);
- gst_structure_get_int (structure, "height", &smokeenc->height);
-
- othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
- gst_caps_set_simple (othercaps,
- "width", G_TYPE_INT, smokeenc->width,
- "height", G_TYPE_INT, smokeenc->height,
- "framerate", GST_TYPE_FRACTION, smokeenc->fps_num, smokeenc->fps_denom,
- NULL);
-
- ret = gst_pad_set_caps (smokeenc->srcpad, othercaps);
- gst_caps_unref (othercaps);
-
- if (GST_PAD_LINK_SUCCESSFUL (ret)) {
- gst_smokeenc_resync (smokeenc);
- }
-
- gst_object_unref (smokeenc);
-
- return ret;
-}
-
-static void
-gst_smokeenc_resync (GstSmokeEnc * smokeenc)
-{
- GST_DEBUG ("gst_smokeenc_resync: resync");
-
- smokecodec_encode_new (&smokeenc->info, smokeenc->width, smokeenc->height,
- smokeenc->fps_num, smokeenc->fps_denom);
- smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
- smokeenc->max_quality);
-
- GST_DEBUG ("gst_smokeenc_resync: resync done");
-}
-
-static GstFlowReturn
-gst_smokeenc_chain (GstPad * pad, GstBuffer * buf)
-{
- GstSmokeEnc *smokeenc;
- guchar *data, *outdata;
- gulong size;
- gint outsize;
- guint encsize;
- GstBuffer *outbuf;
- SmokeCodecFlags flags;
- GstFlowReturn ret;
-
- smokeenc = GST_SMOKEENC (GST_OBJECT_PARENT (pad));
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- GST_DEBUG ("gst_smokeenc_chain: got buffer of %ld bytes in '%s'", size,
- GST_OBJECT_NAME (smokeenc));
-
- if (smokeenc->need_header) {
- outbuf = gst_buffer_new ();
- outsize = 256;
- outdata = g_malloc (outsize);
- GST_BUFFER_DATA (outbuf) = outdata;
- GST_BUFFER_MALLOCDATA (outbuf) = outdata;
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
-
- smokecodec_encode_id (smokeenc->info, outdata, &encsize);
-
- GST_BUFFER_SIZE (outbuf) = encsize;
-
- ret = gst_pad_push (smokeenc->srcpad, outbuf);
-
- smokeenc->need_header = FALSE;
- }
-
- outbuf = gst_buffer_new ();
- outsize = smokeenc->width * smokeenc->height * 3;
- outdata = g_malloc (outsize);
- GST_BUFFER_DATA (outbuf) = outdata;
- GST_BUFFER_MALLOCDATA (outbuf) = outdata;
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) =
- smokeenc->fps_denom * GST_SECOND / smokeenc->fps_num;
-
- flags = 0;
- if ((smokeenc->frame % smokeenc->keyframe) == 0) {
- flags |= SMOKECODEC_KEYFRAME;
- }
- smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
- smokeenc->max_quality);
- smokecodec_set_threshold (smokeenc->info, smokeenc->threshold);
- smokecodec_encode (smokeenc->info, data, flags, outdata, &encsize);
- gst_buffer_unref (buf);
-
- GST_BUFFER_SIZE (outbuf) = encsize;
- GST_BUFFER_OFFSET (outbuf) = smokeenc->frame;
- GST_BUFFER_OFFSET_END (outbuf) = smokeenc->frame + 1;
-
- ret = gst_pad_push (smokeenc->srcpad, outbuf);
-
- smokeenc->frame++;
-
- return ret;
-}
-
-static void
-gst_smokeenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstSmokeEnc *smokeenc;
-
- g_return_if_fail (GST_IS_SMOKEENC (object));
- smokeenc = GST_SMOKEENC (object);
-
- switch (prop_id) {
- case ARG_MIN_QUALITY:
- smokeenc->min_quality = g_value_get_int (value);
- break;
- case ARG_MAX_QUALITY:
- smokeenc->max_quality = g_value_get_int (value);
- break;
- case ARG_THRESHOLD:
- smokeenc->threshold = g_value_get_int (value);
- break;
- case ARG_KEYFRAME:
- smokeenc->keyframe = g_value_get_int (value);
- break;
- default:
- break;
- }
-}
-
-static void
-gst_smokeenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstSmokeEnc *smokeenc;
-
- g_return_if_fail (GST_IS_SMOKEENC (object));
- smokeenc = GST_SMOKEENC (object);
-
- switch (prop_id) {
- case ARG_MIN_QUALITY:
- g_value_set_int (value, smokeenc->min_quality);
- break;
- case ARG_MAX_QUALITY:
- g_value_set_int (value, smokeenc->max_quality);
- break;
- case ARG_THRESHOLD:
- g_value_set_int (value, smokeenc->threshold);
- break;
- case ARG_KEYFRAME:
- g_value_set_int (value, smokeenc->keyframe);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/ext/jpeg/gstsmokeenc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_SMOKEENC_H__
-#define __GST_SMOKEENC_H__
-
-
-#include <gst/gst.h>
-#include "smokecodec.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SMOKEENC \
- (gst_smokeenc_get_type())
-#define GST_SMOKEENC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SMOKEENC,GstSmokeEnc))
-#define GST_SMOKEENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SMOKEENC,GstSmokeEnc))
-#define GST_IS_SMOKEENC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SMOKEENC))
-#define GST_IS_SMOKEENC_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SMOKEENC))
-
-typedef struct _GstSmokeEnc GstSmokeEnc;
-typedef struct _GstSmokeEncClass GstSmokeEncClass;
-
-struct _GstSmokeEnc {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad,*srcpad;
-
- /* video state */
- gint format;
- gint width;
- gint height;
- gint frame;
- gint keyframe;
- gint fps_num, fps_denom;
-
- SmokeCodecInfo *info;
-
- gint threshold;
- gint min_quality;
- gint max_quality;
-
- gboolean need_header;
-};
-
-struct _GstSmokeEncClass {
- GstElementClass parent_class;
-};
-
-GType gst_smokeenc_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_SMOKEENC_H__ */
--- a/gst_plugins_good/ext/jpeg/smokecodec.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,715 +0,0 @@
-/* Smoke codec
- * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-/* this is a hack hack hack to get around jpeglib header bugs... */
-#ifdef HAVE_STDLIB_H
-# undef HAVE_STDLIB_H
-#endif
-#include <jpeglib.h>
-
-#include "smokecodec.h"
-#include "smokeformat.h"
-
-#ifdef SYMBIAN
-#define DEBUG(a...) printf( a );
-#else // SYMBIAN
-#ifndef WIN32
-//#define DEBUG(a...) printf( a );
-#define DEBUG(a,...)
-#else
-#include <gst/gstinfo.h>
-#define DEBUG GST_DEBUG
-#endif
-#endif // SYMBIAN
-
-
-struct _SmokeCodecInfo
-{
- unsigned int width;
- unsigned int height;
- unsigned int fps_num;
- unsigned int fps_denom;
-
- unsigned int minquality;
- unsigned int maxquality;
- unsigned int bitrate;
- unsigned int threshold;
-
- unsigned int refdec;
-
- unsigned char **line[3];
- unsigned char *compbuf[3];
-
- struct jpeg_error_mgr jerr;
-
- struct jpeg_compress_struct cinfo;
- struct jpeg_destination_mgr jdest;
-
- struct jpeg_decompress_struct dinfo;
- struct jpeg_source_mgr jsrc;
-
- int need_keyframe;
- unsigned char *reference;
-};
-
-static void
-smokecodec_init_destination (j_compress_ptr cinfo)
-{
-}
-
-static int
-smokecodec_flush_destination (j_compress_ptr cinfo)
-{
- return 1;
-}
-
-static void
-smokecodec_term_destination (j_compress_ptr cinfo)
-{
-}
-
-static void
-smokecodec_init_source (j_decompress_ptr cinfo)
-{
-}
-
-static int
-smokecodec_fill_input_buffer (j_decompress_ptr cinfo)
-{
- return 1;
-}
-
-static void
-smokecodec_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-{
-}
-
-static int
-smokecodec_resync_to_restart (j_decompress_ptr cinfo, int desired)
-{
- return 1;
-}
-
-static void
-smokecodec_term_source (j_decompress_ptr cinfo)
-{
-}
-
-
-int
-smokecodec_encode_new (SmokeCodecInfo ** info,
- const unsigned int width,
- const unsigned int height,
- const unsigned int fps_num, const unsigned int fps_denom)
-{
- SmokeCodecInfo *newinfo;
- int i, j;
- unsigned char *base[3];
-
- if (!info)
- return SMOKECODEC_NULLPTR;
- if ((width & 0xf) || (height & 0xf))
- return SMOKECODEC_WRONGSIZE;
-
- newinfo = malloc (sizeof (SmokeCodecInfo));
- if (!newinfo) {
- return SMOKECODEC_NOMEM;
- }
- newinfo->width = width;
- newinfo->height = height;
- newinfo->fps_num = fps_num;
- newinfo->fps_denom = fps_denom;
-
- /* setup jpeglib */
- memset (&newinfo->cinfo, 0, sizeof (newinfo->cinfo));
- memset (&newinfo->jerr, 0, sizeof (newinfo->jerr));
- newinfo->cinfo.err = jpeg_std_error (&newinfo->jerr);
- jpeg_create_compress (&newinfo->cinfo);
- newinfo->cinfo.input_components = 3;
- jpeg_set_defaults (&newinfo->cinfo);
-
- newinfo->cinfo.dct_method = JDCT_FASTEST;
-
- newinfo->cinfo.raw_data_in = TRUE;
- newinfo->cinfo.in_color_space = JCS_YCbCr;
- newinfo->cinfo.comp_info[0].h_samp_factor = 2;
- newinfo->cinfo.comp_info[0].v_samp_factor = 2;
- newinfo->cinfo.comp_info[1].h_samp_factor = 1;
- newinfo->cinfo.comp_info[1].v_samp_factor = 1;
- newinfo->cinfo.comp_info[2].h_samp_factor = 1;
- newinfo->cinfo.comp_info[2].v_samp_factor = 1;
-
- newinfo->line[0] = malloc (DCTSIZE * 2 * sizeof (char *));
- newinfo->line[1] = malloc (DCTSIZE * sizeof (char *));
- newinfo->line[2] = malloc (DCTSIZE * sizeof (char *));
- base[0] = newinfo->compbuf[0] = malloc (256 * 2 * DCTSIZE * 2 * DCTSIZE);
- base[1] = newinfo->compbuf[1] = malloc (256 * DCTSIZE * DCTSIZE);
- base[2] = newinfo->compbuf[2] = malloc (256 * DCTSIZE * DCTSIZE);
-
- for (i = 0, j = 0; i < 2 * DCTSIZE; i += 2, j++) {
- newinfo->line[0][i] = base[0];
- base[0] += 2 * DCTSIZE * 256;
- newinfo->line[0][i + 1] = base[0];
- base[0] += 2 * DCTSIZE * 256;
- newinfo->line[1][j] = base[1];
- base[1] += DCTSIZE * 256;
- newinfo->line[2][j] = base[2];
- base[2] += DCTSIZE * 256;
- }
-
- newinfo->jdest.init_destination = smokecodec_init_destination;
- newinfo->jdest.empty_output_buffer = smokecodec_flush_destination;
- newinfo->jdest.term_destination = smokecodec_term_destination;
- newinfo->cinfo.dest = &newinfo->jdest;
-
- jpeg_suppress_tables (&newinfo->cinfo, FALSE);
-
- memset (&newinfo->dinfo, 0, sizeof (newinfo->dinfo));
- newinfo->dinfo.err = jpeg_std_error (&newinfo->jerr);
- jpeg_create_decompress (&newinfo->dinfo);
-
- newinfo->jsrc.init_source = smokecodec_init_source;
- newinfo->jsrc.fill_input_buffer = smokecodec_fill_input_buffer;
- newinfo->jsrc.skip_input_data = smokecodec_skip_input_data;
- newinfo->jsrc.resync_to_restart = smokecodec_resync_to_restart;
- newinfo->jsrc.term_source = smokecodec_term_source;
- newinfo->dinfo.src = &newinfo->jsrc;
-
- newinfo->need_keyframe = 1;
- newinfo->threshold = 4000;
- newinfo->minquality = 10;
- newinfo->maxquality = 85;
- newinfo->reference = malloc (3 * (width * height) / 2);
- newinfo->refdec = 0;
-
- *info = newinfo;
-
- return SMOKECODEC_OK;
-}
-
-int
-smokecodec_decode_new (SmokeCodecInfo ** info)
-{
- return smokecodec_encode_new (info, 16, 16, 1, 1);
-}
-
-int
-smokecodec_info_free (SmokeCodecInfo * info)
-{
- free (info->line[0]);
- free (info->line[1]);
- free (info->line[2]);
- free (info->compbuf[0]);
- free (info->compbuf[1]);
- free (info->compbuf[2]);
- free (info->reference);
- jpeg_destroy_compress (&info->cinfo);
- jpeg_destroy_decompress (&info->dinfo);
- free (info);
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_set_quality (SmokeCodecInfo * info,
- const unsigned int min, const unsigned int max)
-{
- info->minquality = min;
- info->maxquality = max;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_get_quality (SmokeCodecInfo * info,
- unsigned int *min, unsigned int *max)
-{
- *min = info->minquality;
- *max = info->maxquality;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_set_threshold (SmokeCodecInfo * info, const unsigned int threshold)
-{
- info->threshold = threshold;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_get_threshold (SmokeCodecInfo * info, unsigned int *threshold)
-{
- *threshold = info->threshold;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_set_bitrate (SmokeCodecInfo * info, const unsigned int bitrate)
-{
- info->bitrate = bitrate;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_get_bitrate (SmokeCodecInfo * info, unsigned int *bitrate)
-{
- *bitrate = info->bitrate;
-
- return SMOKECODEC_OK;
-}
-
-static void
-find_best_size (int blocks, unsigned int *width, unsigned int *height)
-{
- int sqchng;
- int w, h;
- int best, bestw;
- int free;
-
- sqchng = ceil (sqrt (blocks));
- w = sqchng;
- h = sqchng;
-
- DEBUG ("guess: %d %d\n", w, h);
-
- free = w * h - blocks;
- best = free;
- bestw = w;
-
- while (w < 256) {
- DEBUG ("current: %d %d\n", w, h);
- if (free < best) {
- best = free;
- bestw = w;
- if (free == 0)
- break;
- }
- // if we cannot reduce the height, increase width
- if (free < w) {
- w++;
- free += h;
- }
- // reduce height while possible
- while (free >= w) {
- h--;
- free -= w;
- }
- }
- *width = bestw;
- *height = (blocks + best) / bestw;
-}
-
-static int
-abs_diff (const unsigned char *in1, const unsigned char *in2, const int stride)
-{
- int s;
- int i, j, diff;
-
- s = 0;
-
- for (i = 0; i < 2 * DCTSIZE; i++) {
- for (j = 0; j < 2 * DCTSIZE; j++) {
- diff = in1[j] - in2[j];
- s += diff * diff;
- }
- in1 += stride;
- in2 += stride;
- }
- return s;
-}
-
-static void
-put (const unsigned char *src, unsigned char *dest,
- int width, int height, int srcstride, int deststride)
-{
- int i, j;
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- dest[j] = src[j];
- }
- src += srcstride;
- dest += deststride;
- }
-}
-
-/* encoding */
-SmokeCodecResult
-smokecodec_encode_id (SmokeCodecInfo * info,
- unsigned char *out, unsigned int *outsize)
-{
- int i;
-
- *out++ = SMOKECODEC_TYPE_ID;
- for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
- *out++ = SMOKECODEC_ID_STRING[i];
- }
- *out++ = 0;
- *out++ = 1;
- *out++ = 0;
-
- *outsize = 9;
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_encode (SmokeCodecInfo * info,
- const unsigned char *in,
- SmokeCodecFlags flags, unsigned char *out, unsigned int *outsize)
-{
- unsigned int i, j, s;
- const unsigned char *ip;
- unsigned char *op;
- unsigned int blocks, encoding;
- unsigned int size;
- unsigned int width, height;
- unsigned int blocks_w, blocks_h;
- unsigned int threshold;
- unsigned int max;
-
- if (info->need_keyframe) {
- flags |= SMOKECODEC_KEYFRAME;
- info->need_keyframe = 0;
- }
-
- if (flags & SMOKECODEC_KEYFRAME)
- threshold = 0;
- else
- threshold = info->threshold;
-
- ip = in;
- op = info->reference;
-
- width = info->width;
- height = info->height;
-
- blocks_w = width / (DCTSIZE * 2);
- blocks_h = height / (DCTSIZE * 2);
-
- max = blocks_w * blocks_h;
-
- out[IDX_TYPE] = SMOKECODEC_TYPE_DATA;
-
-#define STORE16(var, pos, x) \
- var[pos] = (x >> 8); \
- var[pos+1] = (x & 0xff);
-#define STORE32(var, pos, x) \
- var[pos] = ((x >> 24) & 0xff); \
- var[pos+1] = ((x >> 16) & 0xff); \
- var[pos+2] = ((x >> 8) & 0xff); \
- var[pos+3] = (x & 0xff);
-
- /* write dimension */
- STORE16 (out, IDX_WIDTH, width);
- STORE16 (out, IDX_HEIGHT, height);
-
- /* write framerate */
- STORE32 (out, IDX_FPS_NUM, info->fps_num);
- STORE32 (out, IDX_FPS_DENOM, info->fps_denom);
-
- if (!(flags & SMOKECODEC_KEYFRAME)) {
- int block = 0;
-
- blocks = 0;
- for (i = 0; i < height; i += 2 * DCTSIZE) {
- for (j = 0; j < width; j += 2 * DCTSIZE) {
- s = abs_diff (ip, op, width);
- if (s >= threshold) {
- STORE16 (out, blocks * 2 + IDX_BLOCKS, block);
- blocks++;
- }
-
- ip += 2 * DCTSIZE;
- op += 2 * DCTSIZE;
- block++;
- }
- ip += (2 * DCTSIZE - 1) * width;
- op += (2 * DCTSIZE - 1) * width;
- }
- if (blocks == max) {
- flags |= SMOKECODEC_KEYFRAME;
- blocks = 0;
- encoding = max;
- } else {
- encoding = blocks;
- }
- } else {
- blocks = 0;
- encoding = max;
- }
- STORE16 (out, IDX_NUM_BLOCKS, blocks);
- out[IDX_FLAGS] = (flags & 0xff);
-
- DEBUG ("blocks %d, encoding %d\n", blocks, encoding);
-
- info->jdest.next_output_byte = &out[blocks * 2 + OFFS_PICT];
- info->jdest.free_in_buffer = (*outsize) - OFFS_PICT;
-
- if (encoding > 0) {
- int quality;
-
- if (!(flags & SMOKECODEC_KEYFRAME))
- find_best_size (encoding, &blocks_w, &blocks_h);
-
- DEBUG ("best: %d %d\n", blocks_w, blocks_h);
-
- info->cinfo.image_width = blocks_w * DCTSIZE * 2;
- info->cinfo.image_height = blocks_h * DCTSIZE * 2;
-
- if (flags & SMOKECODEC_KEYFRAME) {
- quality = (info->maxquality * 60) / 100;
- } else {
- quality =
- info->maxquality - ((info->maxquality -
- info->minquality) * blocks) / max;
- }
-
- DEBUG ("set q %d %d %d\n", quality, encoding, max);
- jpeg_set_quality (&info->cinfo, quality, TRUE);
- DEBUG ("start\n");
- jpeg_start_compress (&info->cinfo, TRUE);
-
- for (i = 0; i < encoding; i++) {
- int pos;
- int x, y;
-
- if (flags & SMOKECODEC_KEYFRAME)
- pos = i;
- else
- pos = (out[i * 2 + IDX_BLOCKS] << 8) | (out[i * 2 + IDX_BLOCKS + 1]);
-
- x = pos % (width / (DCTSIZE * 2));
- y = pos / (width / (DCTSIZE * 2));
-
- ip = in + (x * (DCTSIZE * 2)) + (y * (DCTSIZE * 2) * width);
- op = info->compbuf[0] + (i % blocks_w) * (DCTSIZE * 2);
- put (ip, op, 2 * DCTSIZE, 2 * DCTSIZE, width, 256 * (DCTSIZE * 2));
-
- ip = in + width * height + (x * DCTSIZE) + (y * DCTSIZE * width / 2);
- op = info->compbuf[1] + (i % blocks_w) * (DCTSIZE);
- put (ip, op, DCTSIZE, DCTSIZE, width / 2, 256 * DCTSIZE);
-
- ip = in + 5 * (width * height) / 4 + (x * DCTSIZE) +
- (y * DCTSIZE * width / 2);
- op = info->compbuf[2] + (i % blocks_w) * (DCTSIZE);
- put (ip, op, DCTSIZE, DCTSIZE, width / 2, 256 * DCTSIZE);
-
- if ((i % blocks_w) == (blocks_w - 1) || (i == encoding - 1)) {
- DEBUG ("write %d\n", pos);
- jpeg_write_raw_data (&info->cinfo, info->line, 2 * DCTSIZE);
- }
- }
- DEBUG ("finish\n");
- jpeg_finish_compress (&info->cinfo);
- }
-
- size = ((((*outsize) - OFFS_PICT - info->jdest.free_in_buffer) + 3) & ~3);
- STORE16 (out, IDX_SIZE, size);
-
- *outsize = size + blocks * 2 + OFFS_PICT;
- DEBUG ("outsize %d\n", *outsize);
-
- // and decode in reference frame again
- if (info->refdec) {
- smokecodec_decode (info, out, *outsize, info->reference);
- } else {
- memcpy (info->reference, in, 3 * (width * height) / 2);
- }
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_parse_id (SmokeCodecInfo * info,
- const unsigned char *in, const unsigned int insize)
-{
- int i;
-
- if (insize < 4 + strlen (SMOKECODEC_ID_STRING)) {
- return SMOKECODEC_WRONGVERSION;
- }
-
- if (*in++ != SMOKECODEC_TYPE_ID)
- return SMOKECODEC_ERROR;
-
- for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
- if (*in++ != SMOKECODEC_ID_STRING[i])
- return SMOKECODEC_ERROR;
- }
- if (*in++ != 0 || *in++ != 1 || *in++ != 0)
- return SMOKECODEC_ERROR;
-
- return SMOKECODEC_OK;
-}
-
-#define READ16(var, pos, x) \
- x = var[pos]<<8 | var[pos+1];
-
-#define READ32(var, pos, x) \
- x = var[pos]<<24 | var[pos+1]<<16 | \
- var[pos+2]<<8 | var[pos+3];
-
-/* decoding */
-SmokeCodecResult
-smokecodec_parse_header (SmokeCodecInfo * info,
- const unsigned char *in,
- const unsigned int insize,
- SmokeCodecFlags * flags,
- unsigned int *width,
- unsigned int *height, unsigned int *fps_num, unsigned int *fps_denom)
-{
-
- READ16 (in, IDX_WIDTH, *width);
- READ16 (in, IDX_HEIGHT, *height);
- *flags = in[IDX_FLAGS];
- READ32 (in, IDX_FPS_NUM, *fps_num);
- READ32 (in, IDX_FPS_DENOM, *fps_denom);
-
- if (info->width != *width ||
- info->height != *height ||
- info->fps_num != *fps_num || info->fps_denom != *fps_denom) {
- DEBUG ("new width: %d %d\n", *width, *height);
-
- info->reference = realloc (info->reference, 3 * ((*width) * (*height)) / 2);
- info->width = *width;
- info->height = *height;
- info->fps_num = *fps_num;
- info->fps_denom = *fps_denom;
- }
-
- return SMOKECODEC_OK;
-}
-
-SmokeCodecResult
-smokecodec_decode (SmokeCodecInfo * info,
- const unsigned char *in, const unsigned int insize, unsigned char *out)
-{
- unsigned int width, height;
- unsigned int fps_num, fps_denom;
- SmokeCodecFlags flags;
- int i, j;
- int blocks_w, blocks_h;
- int blockptr;
- int blocks, decoding;
- const unsigned char *ip;
- unsigned char *op;
- int res;
-
- smokecodec_parse_header (info, in, insize, &flags, &width, &height,
- &fps_num, &fps_denom);
-
- READ16 (in, IDX_NUM_BLOCKS, blocks);
- DEBUG ("blocks %d\n", blocks);
-
- if (flags & SMOKECODEC_KEYFRAME)
- decoding = width / (DCTSIZE * 2) * height / (DCTSIZE * 2);
- else
- decoding = blocks;
-
- if (decoding > 0) {
- info->jsrc.next_input_byte = &in[blocks * 2 + OFFS_PICT];
- info->jsrc.bytes_in_buffer = insize - (blocks * 2 + OFFS_PICT);
-
- DEBUG ("header %02x %d\n", in[blocks * 2 + OFFS_PICT], insize);
- res = jpeg_read_header (&info->dinfo, TRUE);
- DEBUG ("header %d %d %d\n", res, info->dinfo.image_width,
- info->dinfo.image_height);
-
- blocks_w = info->dinfo.image_width / (2 * DCTSIZE);
- blocks_h = info->dinfo.image_height / (2 * DCTSIZE);
-
- info->dinfo.output_width = info->dinfo.image_width;
- info->dinfo.output_height = info->dinfo.image_height;
-
- DEBUG ("start\n");
- info->dinfo.do_fancy_upsampling = FALSE;
- info->dinfo.do_block_smoothing = FALSE;
- info->dinfo.out_color_space = JCS_YCbCr;
- info->dinfo.dct_method = JDCT_IFAST;
- info->dinfo.raw_data_out = TRUE;
- jpeg_start_decompress (&info->dinfo);
-
- blockptr = 0;
-
- for (i = 0; i < blocks_h; i++) {
- DEBUG ("read\n");
- jpeg_read_raw_data (&info->dinfo, info->line, 2 * DCTSIZE);
-
- DEBUG ("copy %d\n", blocks_w);
- for (j = 0; j < blocks_w; j++) {
- int pos;
- int x, y;
-
- if (flags & SMOKECODEC_KEYFRAME)
- pos = blockptr;
- else
- READ16 (in, blockptr * 2 + IDX_BLOCKS, pos);
-
- x = pos % (width / (DCTSIZE * 2));
- y = pos / (width / (DCTSIZE * 2));
-
- DEBUG ("block %d %d %d\n", pos, x, y);
-
- ip = info->compbuf[0] + j * (DCTSIZE * 2);
- op = info->reference + (x * (DCTSIZE * 2)) +
- (y * (DCTSIZE * 2) * width);
- put (ip, op, 2 * DCTSIZE, 2 * DCTSIZE, 256 * (DCTSIZE * 2), width);
-
- ip = info->compbuf[1] + j * (DCTSIZE);
- op = info->reference + width * height + (x * DCTSIZE) +
- (y * DCTSIZE * width / 2);
- put (ip, op, DCTSIZE, DCTSIZE, 256 * DCTSIZE, width / 2);
-
- ip = info->compbuf[2] + j * (DCTSIZE);
- op = info->reference + 5 * (width * height) / 4 + (x * DCTSIZE) +
- (y * DCTSIZE * width / 2);
- put (ip, op, DCTSIZE, DCTSIZE, 256 * DCTSIZE, width / 2);
-
- DEBUG ("block done %d %d %d\n", pos, x, y);
- blockptr++;
- if (blockptr >= decoding)
- break;
- }
- }
- DEBUG ("finish\n");
- jpeg_finish_decompress (&info->dinfo);
- }
-
- DEBUG ("copy\n");
- if (out != info->reference)
- memcpy (out, info->reference, 3 * (width * height) / 2);
- DEBUG ("copy done\n");
-
- return SMOKECODEC_OK;
-}
--- a/gst_plugins_good/ext/jpeg/smokecodec.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* Smoke Codec
- * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __SMOKECODEC_H__
-#define __SMOKECODEC_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-typedef struct _SmokeCodecInfo SmokeCodecInfo;
-
-typedef enum {
- SMOKECODEC_WRONGVERSION = -5,
- SMOKECODEC_WRONGSIZE = -4,
- SMOKECODEC_ERROR = -3,
- SMOKECODEC_NOMEM = -2,
- SMOKECODEC_NULLPTR = -1,
- SMOKECODEC_OK = 0
-} SmokeCodecResult;
-
-typedef enum {
- SMOKECODEC_KEYFRAME = (1<<0),
- SMOKECODEC_MOTION_VECTORS = (1<<1)
-} SmokeCodecFlags;
-
-#define SMOKECODEC_ID_STRING "smoke"
-
-typedef enum {
- SMOKECODEC_TYPE_ID = 0x80,
- SMOKECODEC_TYPE_COMMENT = 0x81,
- SMOKECODEC_TYPE_EXTRA = 0x83,
- SMOKECODEC_TYPE_DATA = 0x40
-} SmokePacketType;
-
-/* init */
-int smokecodec_encode_new (SmokeCodecInfo **info,
- const unsigned int width,
- const unsigned int height,
- const unsigned int fps_num,
- const unsigned int fps_denom);
-
-int smokecodec_decode_new (SmokeCodecInfo **info);
-
-int smokecodec_info_free (SmokeCodecInfo * info);
-
-/* config */
-SmokeCodecResult smokecodec_set_quality (SmokeCodecInfo *info,
- const unsigned int min,
- const unsigned int max);
-SmokeCodecResult smokecodec_get_quality (SmokeCodecInfo *info,
- unsigned int *min,
- unsigned int *max);
-
-SmokeCodecResult smokecodec_set_threshold (SmokeCodecInfo *info,
- const unsigned int threshold);
-SmokeCodecResult smokecodec_get_threshold (SmokeCodecInfo *info,
- unsigned int *threshold);
-
-SmokeCodecResult smokecodec_set_bitrate (SmokeCodecInfo *info,
- const unsigned int bitrate);
-SmokeCodecResult smokecodec_get_bitrate (SmokeCodecInfo *info,
- unsigned int *bitrate);
-
-/* encoding */
-SmokeCodecResult smokecodec_encode_id (SmokeCodecInfo *info,
- unsigned char *out,
- unsigned int *outsize);
-
-SmokeCodecResult smokecodec_encode (SmokeCodecInfo *info,
- const unsigned char *in,
- SmokeCodecFlags flags,
- unsigned char *out,
- unsigned int *outsize);
-
-/* decoding */
-SmokeCodecResult smokecodec_parse_id (SmokeCodecInfo *info,
- const unsigned char *in,
- const unsigned int insize);
-
-SmokeCodecResult smokecodec_parse_header (SmokeCodecInfo *info,
- const unsigned char *in,
- const unsigned int insize,
- SmokeCodecFlags *flags,
- unsigned int *width,
- unsigned int *height,
- unsigned int *fps_num,
- unsigned int *fps_denom);
-
-SmokeCodecResult smokecodec_decode (SmokeCodecInfo *info,
- const unsigned char *in,
- const unsigned int insize,
- unsigned char *out);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __SMOKECODEC_H__ */
--- a/gst_plugins_good/ext/jpeg/smokeformat.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/* Smoke Codec
- * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __SMOKEFORMAT_H__
-#define __SMOKEFORMAT_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define IDX_TYPE 0
-#define IDX_WIDTH 1
-#define IDX_HEIGHT 3
-#define IDX_FPS_NUM 5
-#define IDX_FPS_DENOM 9
-#define IDX_FLAGS 13
-#define IDX_NUM_BLOCKS 14
-#define IDX_SIZE 16
-#define IDX_BLOCKS 18
-#define OFFS_PICT 18
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __SMOKEFORMAT_H__ */
--- a/gst_plugins_good/ext/libpng/gstpng.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * Filter:
- * Copyright (C) 2000 Donald A. Graft
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <gst/gst.h>
-
-#include "gstpngdec.h"
-#include "gstpngenc.h"
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "pngdec", GST_RANK_PRIMARY,
- GST_TYPE_PNGDEC))
- return FALSE;
-
- if (!gst_element_register (plugin, "pngenc", GST_RANK_PRIMARY,
- GST_TYPE_PNGENC))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "png",
- "PNG plugin library", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
- GST_PACKAGE_ORIGIN)
-
-#ifdef __SYMBIAN32__
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-#endif
--- a/gst_plugins_good/ext/libpng/gstpngdec.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,881 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-/**
- * SECTION:element-pngdec
- *
- * Decodes png images. If there is no framerate set on sink caps, it sends EOS
- * after the first picture.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstpngdec.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <gst/video/video.h>
-#include <gst/gst-i18n-plugin.h>
-
-static const GstElementDetails gst_pngdec_details =
-GST_ELEMENT_DETAILS ("PNG image decoder",
- "Codec/Decoder/Image",
- "Decode a png video frame to a raw image",
- "Wim Taymans <wim@fluendo.com>");
-
-GST_DEBUG_CATEGORY_STATIC (pngdec_debug);
-#define GST_CAT_DEFAULT pngdec_debug
-
-static void gst_pngdec_base_init (gpointer g_class);
-static void gst_pngdec_class_init (GstPngDecClass * klass);
-static void gst_pngdec_init (GstPngDec * pngdec);
-
-static gboolean gst_pngdec_libpng_init (GstPngDec * pngdec);
-static gboolean gst_pngdec_libpng_clear (GstPngDec * pngdec);
-
-static GstStateChangeReturn gst_pngdec_change_state (GstElement * element,
- GstStateChange transition);
-
-static gboolean gst_pngdec_sink_activate_push (GstPad * sinkpad,
- gboolean active);
-static gboolean gst_pngdec_sink_activate_pull (GstPad * sinkpad,
- gboolean active);
-static gboolean gst_pngdec_sink_activate (GstPad * sinkpad);
-
-static GstFlowReturn gst_pngdec_caps_create_and_set (GstPngDec * pngdec);
-
-static void gst_pngdec_task (GstPad * pad);
-static GstFlowReturn gst_pngdec_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_pngdec_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_pngdec_sink_setcaps (GstPad * pad, GstCaps * caps);
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_pngdec_get_type (void)
-{
- static GType pngdec_type = 0;
-
- if (!pngdec_type) {
- static const GTypeInfo pngdec_info = {
- sizeof (GstPngDecClass),
- gst_pngdec_base_init,
- NULL,
- (GClassInitFunc) gst_pngdec_class_init,
- NULL,
- NULL,
- sizeof (GstPngDec),
- 0,
- (GInstanceInitFunc) gst_pngdec_init,
- };
-
- pngdec_type = g_type_register_static (GST_TYPE_ELEMENT, "GstPngDec",
- &pngdec_info, 0);
- }
- return pngdec_type;
-}
-
-static GstStaticPadTemplate gst_pngdec_src_pad_template =
- GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB)
- );
-
-static GstStaticPadTemplate gst_pngdec_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/png")
- );
-
-static void
-gst_pngdec_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_pngdec_src_pad_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_pngdec_sink_pad_template));
- gst_element_class_set_details (element_class, &gst_pngdec_details);
-}
-
-static void
-gst_pngdec_class_init (GstPngDecClass * klass)
-{
- GstElementClass *gstelement_class;
-
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gstelement_class->change_state = gst_pngdec_change_state;
-
- GST_DEBUG_CATEGORY_INIT (pngdec_debug, "pngdec", 0, "PNG image decoder");
-}
-
-static void
-gst_pngdec_init (GstPngDec * pngdec)
-{
- pngdec->sinkpad =
- gst_pad_new_from_static_template (&gst_pngdec_sink_pad_template, "sink");
- gst_pad_set_activate_function (pngdec->sinkpad, gst_pngdec_sink_activate);
- gst_pad_set_activatepush_function (pngdec->sinkpad,
- gst_pngdec_sink_activate_push);
- gst_pad_set_activatepull_function (pngdec->sinkpad,
- gst_pngdec_sink_activate_pull);
- gst_pad_set_chain_function (pngdec->sinkpad, gst_pngdec_chain);
- gst_pad_set_event_function (pngdec->sinkpad, gst_pngdec_sink_event);
- gst_pad_set_setcaps_function (pngdec->sinkpad, gst_pngdec_sink_setcaps);
- gst_element_add_pad (GST_ELEMENT (pngdec), pngdec->sinkpad);
-
- pngdec->srcpad =
- gst_pad_new_from_static_template (&gst_pngdec_src_pad_template, "src");
- gst_pad_use_fixed_caps (pngdec->srcpad);
- gst_element_add_pad (GST_ELEMENT (pngdec), pngdec->srcpad);
-
- pngdec->buffer_out = NULL;
- pngdec->png = NULL;
- pngdec->info = NULL;
- pngdec->endinfo = NULL;
- pngdec->setup = FALSE;
-
- pngdec->color_type = -1;
- pngdec->width = -1;
- pngdec->height = -1;
- pngdec->bpp = -1;
- pngdec->fps_n = 0;
- pngdec->fps_d = 1;
-
- pngdec->in_timestamp = GST_CLOCK_TIME_NONE;
- pngdec->in_duration = GST_CLOCK_TIME_NONE;
-
- gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
-
- pngdec->image_ready = FALSE;
-}
-
-static void
-user_error_fn (png_structp png_ptr, png_const_charp error_msg)
-{
- GST_ERROR ("%s", error_msg);
-}
-
-static void
-user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
-{
- GST_WARNING ("%s", warning_msg);
-}
-
-static void
-user_info_callback (png_structp png_ptr, png_infop info)
-{
- GstPngDec *pngdec = NULL;
- GstFlowReturn ret = GST_FLOW_OK;
- size_t buffer_size;
- GstBuffer *buffer = NULL;
-
- pngdec = GST_PNGDEC (png_ptr->io_ptr);
-
- GST_LOG ("info ready");
-
- /* Generate the caps and configure */
- ret = gst_pngdec_caps_create_and_set (pngdec);
- if (ret != GST_FLOW_OK) {
- goto beach;
- }
-
- /* Allocate output buffer */
- pngdec->rowbytes = png_get_rowbytes (pngdec->png, pngdec->info);
- buffer_size = pngdec->height * GST_ROUND_UP_4 (pngdec->rowbytes);
- ret =
- gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE,
- buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer);
- if (ret != GST_FLOW_OK) {
- goto beach;
- }
-
- pngdec->buffer_out = buffer;
-
-beach:
- pngdec->ret = ret;
-}
-
-static void
-user_endrow_callback (png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass)
-{
- GstPngDec *pngdec = NULL;
-
- pngdec = GST_PNGDEC (png_ptr->io_ptr);
-
- /* FIXME: implement interlaced pictures */
-
- /* If buffer_out doesn't exist, it means buffer_alloc failed, which
- * will already have set the return code */
- if (GST_IS_BUFFER (pngdec->buffer_out)) {
- size_t offset = row_num * GST_ROUND_UP_4 (pngdec->rowbytes);
-
- GST_LOG ("got row %u, copying in buffer %p at offset %" G_GSIZE_FORMAT,
- (guint) row_num, pngdec->buffer_out, offset);
- memcpy (GST_BUFFER_DATA (pngdec->buffer_out) + offset, new_row,
- pngdec->rowbytes);
- pngdec->ret = GST_FLOW_OK;
- }
-}
-
-static gboolean
-buffer_clip (GstPngDec * dec, GstBuffer * buffer)
-{
- gboolean res = TRUE;
- gint64 cstart, cstop;
-
-
- if ((!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))) ||
- (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buffer))) ||
- (dec->segment.format != GST_FORMAT_TIME))
- goto beach;
-
- cstart = GST_BUFFER_TIMESTAMP (buffer);
- cstop = GST_BUFFER_DURATION (buffer);
-
- if ((res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
- cstart, cstart + cstop, &cstart, &cstop))) {
- GST_BUFFER_TIMESTAMP (buffer) = cstart;
- GST_BUFFER_DURATION (buffer) = cstop - cstart;
- }
-
-beach:
- return res;
-}
-
-static void
-user_end_callback (png_structp png_ptr, png_infop info)
-{
- GstPngDec *pngdec = NULL;
-
- pngdec = GST_PNGDEC (png_ptr->io_ptr);
-
- GST_LOG_OBJECT (pngdec, "and we are done reading this image");
-
- if (!pngdec->buffer_out)
- return;
-
- if (GST_CLOCK_TIME_IS_VALID (pngdec->in_timestamp))
- GST_BUFFER_TIMESTAMP (pngdec->buffer_out) = pngdec->in_timestamp;
- if (GST_CLOCK_TIME_IS_VALID (pngdec->in_duration))
- GST_BUFFER_DURATION (pngdec->buffer_out) = pngdec->in_duration;
-
- /* buffer clipping */
- if (buffer_clip (pngdec, pngdec->buffer_out)) {
- /* Push our buffer and then EOS if needed */
- GST_LOG_OBJECT (pngdec, "pushing buffer with ts=%" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (pngdec->buffer_out)));
-
- pngdec->ret = gst_pad_push (pngdec->srcpad, pngdec->buffer_out);
- } else {
- GST_LOG_OBJECT (pngdec, "dropped decoded buffer");
- gst_buffer_unref (pngdec->buffer_out);
- }
- pngdec->buffer_out = NULL;
- pngdec->image_ready = TRUE;
-}
-
-static void
-user_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
-{
- GstPngDec *pngdec;
- GstBuffer *buffer;
- GstFlowReturn ret = GST_FLOW_OK;
- guint size;
-
- pngdec = GST_PNGDEC (png_ptr->io_ptr);
-
- GST_LOG ("reading %" G_GSIZE_FORMAT " bytes of data at offset %d", length,
- pngdec->offset);
-
- ret = gst_pad_pull_range (pngdec->sinkpad, pngdec->offset, length, &buffer);
- if (ret != GST_FLOW_OK)
- goto pause;
-
- size = GST_BUFFER_SIZE (buffer);
-
- if (size != length)
- goto short_buffer;
-
- memcpy (data, GST_BUFFER_DATA (buffer), size);
-
- gst_buffer_unref (buffer);
-
- pngdec->offset += length;
-
- return;
-
- /* ERRORS */
-pause:
- {
- GST_INFO_OBJECT (pngdec, "pausing task, reason %s",
- gst_flow_get_name (ret));
- gst_pad_pause_task (pngdec->sinkpad);
- if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
- GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
- (_("Internal data stream error.")),
- ("stream stopped, reason %s", gst_flow_get_name (ret)));
- gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
- }
- return;
- }
-short_buffer:
- {
- gst_buffer_unref (buffer);
- GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
- (_("Internal data stream error.")),
- ("Read %u, needed %" G_GSIZE_FORMAT "bytes", size, length));
- ret = GST_FLOW_ERROR;
- goto pause;
- }
-}
-
-static GstFlowReturn
-gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- GstCaps *caps = NULL, *res = NULL;
- GstPadTemplate *templ = NULL;
- gint bpc = 0, color_type;
- png_uint_32 width, height;
-
- g_return_val_if_fail (GST_IS_PNGDEC (pngdec), GST_FLOW_ERROR);
-
- /* Get bits per channel */
- bpc = png_get_bit_depth (pngdec->png, pngdec->info);
-
- /* We don't handle 16 bits per color, strip down to 8 */
- if (bpc == 16) {
- GST_LOG_OBJECT (pngdec,
- "this is a 16 bits per channel PNG image, strip down to 8 bits");
- png_set_strip_16 (pngdec->png);
- }
-
- /* Get Color type */
- color_type = png_get_color_type (pngdec->png, pngdec->info);
-
-#if 0
- /* We used to have this HACK to reverse the outgoing bytes, but the problem
- * that originally required the hack seems to have been in ffmpegcolorspace's
- * RGBA descriptions. It doesn't seem needed now that's fixed, but might
- * still be needed on big-endian systems, I'm not sure. J.S. 6/7/2007 */
- if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_bgr (pngdec->png);
-#endif
-
- /* Gray scale converted to RGB and upscaled to 8 bits */
- if ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
- (color_type == PNG_COLOR_TYPE_GRAY)) {
- GST_LOG_OBJECT (pngdec, "converting grayscale png to RGB");
- png_set_gray_to_rgb (pngdec->png);
- if (bpc < 8) { /* Convert to 8 bits */
- GST_LOG_OBJECT (pngdec, "converting grayscale image to 8 bits");
- png_set_gray_1_2_4_to_8 (pngdec->png);
- }
- }
-
- /* Palette converted to RGB */
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- GST_LOG_OBJECT (pngdec, "converting palette png to RGB");
- png_set_palette_to_rgb (pngdec->png);
- }
-
- /* Update the info structure */
- png_read_update_info (pngdec->png, pngdec->info);
-
- /* Get IHDR header again after transformation settings */
-
- png_get_IHDR (pngdec->png, pngdec->info, &width, &height,
- &bpc, &pngdec->color_type, NULL, NULL, NULL);
-
- pngdec->width = width;
- pngdec->height = height;
-
- GST_LOG_OBJECT (pngdec, "this is a %dx%d PNG image", pngdec->width,
- pngdec->height);
-
- switch (pngdec->color_type) {
- case PNG_COLOR_TYPE_RGB:
- GST_LOG_OBJECT (pngdec, "we have no alpha channel, depth is 24 bits");
- pngdec->bpp = 24;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- GST_LOG_OBJECT (pngdec, "we have an alpha channel, depth is 32 bits");
- pngdec->bpp = 32;
- break;
- default:
- GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),
- ("pngdec does not support this color type"));
- ret = GST_FLOW_NOT_SUPPORTED;
- goto beach;
- }
-
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "width", G_TYPE_INT, pngdec->width,
- "height", G_TYPE_INT, pngdec->height,
- "bpp", G_TYPE_INT, pngdec->bpp,
- "framerate", GST_TYPE_FRACTION, pngdec->fps_n, pngdec->fps_d, NULL);
-
- templ = gst_static_pad_template_get (&gst_pngdec_src_pad_template);
-
- res = gst_caps_intersect (caps, gst_pad_template_get_caps (templ));
-
- gst_caps_unref (caps);
- gst_object_unref (templ);
-
- if (!gst_pad_set_caps (pngdec->srcpad, res))
- ret = GST_FLOW_NOT_NEGOTIATED;
-
- GST_DEBUG_OBJECT (pngdec, "our caps %" GST_PTR_FORMAT, res);
-
- gst_caps_unref (res);
-
- /* Push a newsegment event */
- if (pngdec->need_newsegment) {
- gst_pad_push_event (pngdec->srcpad,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
- pngdec->need_newsegment = FALSE;
- }
-
-beach:
- return ret;
-}
-
-static void
-gst_pngdec_task (GstPad * pad)
-{
- GstPngDec *pngdec;
- GstBuffer *buffer = NULL;
- size_t buffer_size = 0;
- gint i = 0;
- png_bytep *rows, inp;
- png_uint_32 rowbytes;
- GstFlowReturn ret = GST_FLOW_OK;
-
- pngdec = GST_PNGDEC (GST_OBJECT_PARENT (pad));
-
- GST_LOG_OBJECT (pngdec, "read frame");
-
- /* Let libpng come back here on error */
- if (setjmp (png_jmpbuf (pngdec->png))) {
- ret = GST_FLOW_ERROR;
- goto pause;
- }
-
- /* Set reading callback */
- png_set_read_fn (pngdec->png, pngdec, user_read_data);
-
- /* Read info */
- png_read_info (pngdec->png, pngdec->info);
-
- /* Generate the caps and configure */
- ret = gst_pngdec_caps_create_and_set (pngdec);
- if (ret != GST_FLOW_OK) {
- goto pause;
- }
-
- /* Allocate output buffer */
- rowbytes = png_get_rowbytes (pngdec->png, pngdec->info);
- buffer_size = pngdec->height * GST_ROUND_UP_4 (rowbytes);
- ret =
- gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE,
- buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer);
- if (ret != GST_FLOW_OK)
- goto pause;
-
- rows = (png_bytep *) g_malloc (sizeof (png_bytep) * pngdec->height);
-
- inp = GST_BUFFER_DATA (buffer);
-
- for (i = 0; i < pngdec->height; i++) {
- rows[i] = inp;
- inp += GST_ROUND_UP_4 (rowbytes);
- }
-
- /* Read the actual picture */
- png_read_image (pngdec->png, rows);
- free (rows);
-
- /* Push the raw RGB frame */
- ret = gst_pad_push (pngdec->srcpad, buffer);
- if (ret != GST_FLOW_OK)
- goto pause;
-
- /* And we are done */
- gst_pad_pause_task (pngdec->sinkpad);
- gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
- return;
-
-pause:
- {
- GST_INFO_OBJECT (pngdec, "pausing task, reason %s",
- gst_flow_get_name (ret));
- gst_pad_pause_task (pngdec->sinkpad);
- if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
- GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
- (_("Internal data stream error.")),
- ("stream stopped, reason %s", gst_flow_get_name (ret)));
- gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
- }
- }
-}
-
-static GstFlowReturn
-gst_pngdec_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstPngDec *pngdec;
- GstFlowReturn ret = GST_FLOW_OK;
-
- pngdec = GST_PNGDEC (gst_pad_get_parent (pad));
-
- GST_LOG_OBJECT (pngdec, "Got buffer, size=%u", GST_BUFFER_SIZE (buffer));
-
- if (G_UNLIKELY (!pngdec->setup))
- goto not_configured;
-
- /* Something is going wrong in our callbacks */
- ret = pngdec->ret;
- if (G_UNLIKELY (ret != GST_FLOW_OK)) {
- GST_WARNING_OBJECT (pngdec, "we have a pending return code of %d", ret);
- goto beach;
- }
-
- /* Let libpng come back here on error */
- if (setjmp (png_jmpbuf (pngdec->png))) {
- GST_WARNING_OBJECT (pngdec, "error during decoding");
- ret = GST_FLOW_ERROR;
- goto beach;
- }
-
- pngdec->in_timestamp = GST_BUFFER_TIMESTAMP (buffer);
- pngdec->in_duration = GST_BUFFER_DURATION (buffer);
-
- /* Progressive loading of the PNG image */
- png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-
- if (pngdec->image_ready) {
- if (pngdec->framed) {
- /* Reset ourselves for the next frame */
- gst_pngdec_libpng_clear (pngdec);
- gst_pngdec_libpng_init (pngdec);
- GST_LOG_OBJECT (pngdec, "setting up callbacks for next frame");
- png_set_progressive_read_fn (pngdec->png, pngdec,
- user_info_callback, user_endrow_callback, user_end_callback);
- } else {
- GST_LOG_OBJECT (pngdec, "sending EOS");
- pngdec->ret = gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
- }
- pngdec->image_ready = FALSE;
- }
-
- /* grab new return code */
- ret = pngdec->ret;
-
- /* And release the buffer */
- gst_buffer_unref (buffer);
-
-beach:
- gst_object_unref (pngdec);
-
- return ret;
-
- /* ERRORS */
-not_configured:
- {
- GST_LOG_OBJECT (pngdec, "we are not configured yet");
- ret = GST_FLOW_WRONG_STATE;
- goto beach;
- }
-}
-
-static gboolean
-gst_pngdec_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstStructure *s;
- GstPngDec *pngdec;
- gint num, denom;
-
- pngdec = GST_PNGDEC (gst_pad_get_parent (pad));
-
- s = gst_caps_get_structure (caps, 0);
- if (gst_structure_get_fraction (s, "framerate", &num, &denom)) {
- GST_DEBUG_OBJECT (pngdec, "framed input");
- pngdec->framed = TRUE;
- pngdec->fps_n = num;
- pngdec->fps_d = denom;
- } else {
- GST_DEBUG_OBJECT (pngdec, "single picture input");
- pngdec->framed = FALSE;
- pngdec->fps_n = 0;
- pngdec->fps_d = 1;
- }
-
- gst_object_unref (pngdec);
- return TRUE;
-}
-
-static gboolean
-gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
-{
- GstPngDec *pngdec;
- gboolean res;
-
- pngdec = GST_PNGDEC (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:{
- gdouble rate, arate;
- gboolean update;
- gint64 start, stop, position;
- GstFormat fmt;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
- &start, &stop, &position);
-
- gst_segment_set_newsegment_full (&pngdec->segment, update, rate, arate,
- fmt, start, stop, position);
-
- GST_LOG_OBJECT (pngdec, "NEWSEGMENT (%s)", gst_format_get_name (fmt));
-
- if (fmt == GST_FORMAT_TIME) {
- pngdec->need_newsegment = FALSE;
- res = gst_pad_push_event (pngdec->srcpad, event);
- } else {
- gst_event_unref (event);
- res = TRUE;
- }
- break;
- }
- case GST_EVENT_FLUSH_STOP:
- {
- gst_pngdec_libpng_clear (pngdec);
- gst_pngdec_libpng_init (pngdec);
- png_set_progressive_read_fn (pngdec->png, pngdec,
- user_info_callback, user_endrow_callback, user_end_callback);
- pngdec->ret = GST_FLOW_OK;
- gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
- res = gst_pad_push_event (pngdec->srcpad, event);
- break;
- }
- case GST_EVENT_EOS:
- {
- GST_LOG_OBJECT (pngdec, "EOS");
- gst_pngdec_libpng_clear (pngdec);
- pngdec->ret = GST_FLOW_UNEXPECTED;
- res = gst_pad_push_event (pngdec->srcpad, event);
- break;
- }
- default:
- res = gst_pad_push_event (pngdec->srcpad, event);
- break;
- }
-
- gst_object_unref (pngdec);
- return res;
-}
-
-
-/* Clean up the libpng structures */
-static gboolean
-gst_pngdec_libpng_clear (GstPngDec * pngdec)
-{
- png_infopp info = NULL, endinfo = NULL;
-
- g_return_val_if_fail (GST_IS_PNGDEC (pngdec), FALSE);
-
- GST_LOG ("cleaning up libpng structures");
-
- if (pngdec->info) {
- info = &pngdec->info;
- }
-
- if (pngdec->endinfo) {
- endinfo = &pngdec->endinfo;
- }
-
- if (pngdec->png) {
- png_destroy_read_struct (&(pngdec->png), info, endinfo);
- pngdec->png = NULL;
- pngdec->info = NULL;
- pngdec->endinfo = NULL;
- }
-
- pngdec->bpp = pngdec->color_type = pngdec->height = pngdec->width = -1;
- pngdec->offset = 0;
- pngdec->rowbytes = 0;
- pngdec->buffer_out = NULL;
-
- pngdec->setup = FALSE;
-
- pngdec->in_timestamp = GST_CLOCK_TIME_NONE;
- pngdec->in_duration = GST_CLOCK_TIME_NONE;
-
- return TRUE;
-}
-
-static gboolean
-gst_pngdec_libpng_init (GstPngDec * pngdec)
-{
- g_return_val_if_fail (GST_IS_PNGDEC (pngdec), FALSE);
-
- if (pngdec->setup)
- return TRUE;
-
- GST_LOG ("init libpng structures");
-
- /* initialize png struct stuff */
- pngdec->png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
- (png_voidp) NULL, user_error_fn, user_warning_fn);
-
- if (pngdec->png == NULL)
- goto init_failed;
-
- pngdec->info = png_create_info_struct (pngdec->png);
- if (pngdec->info == NULL)
- goto info_failed;
-
- pngdec->endinfo = png_create_info_struct (pngdec->png);
- if (pngdec->endinfo == NULL)
- goto endinfo_failed;
-
- pngdec->setup = TRUE;
-
- return TRUE;
-
- /* ERRORS */
-init_failed:
- {
- GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
- ("Failed to initialize png structure"));
- return FALSE;
- }
-info_failed:
- {
- gst_pngdec_libpng_clear (pngdec);
- GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
- ("Failed to initialize info structure"));
- return FALSE;
- }
-endinfo_failed:
- {
- gst_pngdec_libpng_clear (pngdec);
- GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
- ("Failed to initialize endinfo structure"));
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_pngdec_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstPngDec *pngdec;
-
- pngdec = GST_PNGDEC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- gst_pngdec_libpng_init (pngdec);
- pngdec->need_newsegment = TRUE;
- pngdec->framed = FALSE;
- pngdec->ret = GST_FLOW_OK;
- gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
- break;
- default:
- break;
- }
-
- ret = parent_class->change_state (element, transition);
- if (ret != GST_STATE_CHANGE_SUCCESS)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_pngdec_libpng_clear (pngdec);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-/* this function gets called when we activate ourselves in push mode. */
-static gboolean
-gst_pngdec_sink_activate_push (GstPad * sinkpad, gboolean active)
-{
- GstPngDec *pngdec;
-
- pngdec = GST_PNGDEC (GST_OBJECT_PARENT (sinkpad));
-
- pngdec->ret = GST_FLOW_OK;
-
- if (active) {
- /* Let libpng come back here on error */
- if (setjmp (png_jmpbuf (pngdec->png)))
- goto setup_failed;
-
- GST_LOG ("setting up progressive loading callbacks");
- png_set_progressive_read_fn (pngdec->png, pngdec,
- user_info_callback, user_endrow_callback, user_end_callback);
- }
- return TRUE;
-
-setup_failed:
- {
- GST_LOG ("failed setting up libpng jmpbuf");
- gst_pngdec_libpng_clear (pngdec);
- return FALSE;
- }
-}
-
-/* this function gets called when we activate ourselves in pull mode.
- * We can perform random access to the resource and we start a task
- * to start reading */
-static gboolean
-gst_pngdec_sink_activate_pull (GstPad * sinkpad, gboolean active)
-{
- if (active) {
- return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_pngdec_task,
- sinkpad);
- } else {
- return gst_pad_stop_task (sinkpad);
- }
-}
-
-/* this function is called when the pad is activated and should start
- * processing data.
- *
- * We check if we can do random access to decide if we work push or
- * pull based.
- */
-static gboolean
-gst_pngdec_sink_activate (GstPad * sinkpad)
-{
- if (gst_pad_check_pull_range (sinkpad)) {
- return gst_pad_activate_pull (sinkpad, TRUE);
- } else {
- return gst_pad_activate_push (sinkpad, TRUE);
- }
-}
--- a/gst_plugins_good/ext/libpng/gstpngdec.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_PNGDEC_H__
-#define __GST_PNGDEC_H__
-
-#include <gst/gst.h>
-#include <png.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define GST_TYPE_PNGDEC (gst_pngdec_get_type())
-#define GST_PNGDEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PNGDEC,GstPngDec))
-#define GST_PNGDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PNGDEC,GstPngDecClass))
-#define GST_IS_PNGDEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PNGDEC))
-#define GST_IS_PNGDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PNGDEC))
-
-typedef struct _GstPngDec GstPngDec;
-typedef struct _GstPngDecClass GstPngDecClass;
-
-struct _GstPngDec
-{
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
-
- gboolean need_newsegment;
-
- /* Progressive */
- GstBuffer *buffer_out;
- GstFlowReturn ret;
- png_uint_32 rowbytes;
-
- /* Pull range */
- gint offset;
-
- png_structp png;
- png_infop info;
- png_infop endinfo;
- gboolean setup;
-
- gint width;
- gint height;
- gint bpp;
- gint color_type;
- gint fps_n;
- gint fps_d;
-
- /* Chain */
- gboolean framed;
- GstClockTime in_timestamp;
- GstClockTime in_duration;
-
- GstSegment segment;
- gboolean image_ready;
-};
-
-struct _GstPngDecClass
-{
- GstElementClass parent_class;
-};
-
-GType gst_pngdec_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __GST_PNGDEC_H__ */
--- a/gst_plugins_good/ext/libpng/gstpngenc.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * Filter:
- * Copyright (C) 2000 Donald A. Graft
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-/**
- * SECTION:element-pngenc
- *
- * Encodes png images.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-#include <gst/gst.h>
-#include "gstpngenc.h"
-#include <gst/video/video.h>
-#include <zlib.h>
-
-#define MAX_HEIGHT 4096
-
-
-static const GstElementDetails gst_pngenc_details =
-GST_ELEMENT_DETAILS ("PNG image encoder",
- "Codec/Encoder/Image",
- "Encode a video frame to a .png image",
- "Jeremy SIMON <jsimon13@yahoo.fr>");
-
-GST_DEBUG_CATEGORY_STATIC (pngenc_debug);
-#define GST_CAT_DEFAULT pngenc_debug
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_SNAPSHOT TRUE
-/* #define DEFAULT_NEWMEDIA FALSE */
-#define DEFAULT_COMPRESSION_LEVEL 6
-
-enum
-{
- ARG_0,
- ARG_SNAPSHOT,
-/* ARG_NEWMEDIA, */
- ARG_COMPRESSION_LEVEL
-};
-
-static GstStaticPadTemplate pngenc_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/png, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0.0, MAX ]")
- );
-
-static GstStaticPadTemplate pngenc_sink_template =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB)
- );
-
-/* static GstElementClass *parent_class = NULL; */
-
-GST_BOILERPLATE (GstPngEnc, gst_pngenc, GstElement, GST_TYPE_ELEMENT);
-
-static void gst_pngenc_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_pngenc_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-
-static GstFlowReturn gst_pngenc_chain (GstPad * pad, GstBuffer * data);
-
-static void
-user_error_fn (png_structp png_ptr, png_const_charp error_msg)
-{
- g_warning ("%s", error_msg);
-}
-
-static void
-user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
-{
- g_warning ("%s", warning_msg);
-}
-
-static void
-gst_pngenc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template
- (element_class, gst_static_pad_template_get (&pngenc_sink_template));
- gst_element_class_add_pad_template
- (element_class, gst_static_pad_template_get (&pngenc_src_template));
- gst_element_class_set_details (element_class, &gst_pngenc_details);
-}
-
-static void
-gst_pngenc_class_init (GstPngEncClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->get_property = gst_pngenc_get_property;
- gobject_class->set_property = gst_pngenc_set_property;
-
- g_object_class_install_property (gobject_class, ARG_SNAPSHOT,
- g_param_spec_boolean ("snapshot", "Snapshot",
- "Send EOS after encoding a frame, useful for snapshots",
- DEFAULT_SNAPSHOT, (GParamFlags) G_PARAM_READWRITE));
-
-/* g_object_class_install_property (gobject_class, ARG_NEWMEDIA, */
-/* g_param_spec_boolean ("newmedia", "newmedia", */
-/* "Send new media discontinuity after encoding each frame", */
-/* DEFAULT_NEWMEDIA, (GParamFlags) G_PARAM_READWRITE)); */
-
- g_object_class_install_property
- (gobject_class, ARG_COMPRESSION_LEVEL,
- g_param_spec_uint ("compression-level", "compression-level",
- "PNG compression level",
- Z_NO_COMPRESSION, Z_BEST_COMPRESSION,
- DEFAULT_COMPRESSION_LEVEL, (GParamFlags) G_PARAM_READWRITE));
-
- GST_DEBUG_CATEGORY_INIT (pngenc_debug, "pngenc", 0, "PNG image encoder");
-}
-
-
-static gboolean
-gst_pngenc_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstPngEnc *pngenc;
- const GValue *fps;
- GstStructure *structure;
- GstCaps *pcaps;
- gboolean ret = TRUE;
-
- pngenc = GST_PNGENC (gst_pad_get_parent (pad));
-
- structure = gst_caps_get_structure (caps, 0);
- gst_structure_get_int (structure, "width", &pngenc->width);
- gst_structure_get_int (structure, "height", &pngenc->height);
- fps = gst_structure_get_value (structure, "framerate");
- gst_structure_get_int (structure, "bpp", &pngenc->bpp);
-
- if (pngenc->bpp == 32)
- pngenc->stride = pngenc->width * 4;
- else
- pngenc->stride = GST_ROUND_UP_4 (pngenc->width * 3);
-
- pcaps = gst_caps_new_simple ("image/png",
- "width", G_TYPE_INT, pngenc->width,
- "height", G_TYPE_INT, pngenc->height, NULL);
- structure = gst_caps_get_structure (pcaps, 0);
- gst_structure_set_value (structure, "framerate", fps);
-
- ret = gst_pad_set_caps (pngenc->srcpad, pcaps);
-
- gst_caps_unref (pcaps);
- gst_object_unref (pngenc);
-
- return ret;
-}
-
-static void
-gst_pngenc_init (GstPngEnc * pngenc, GstPngEncClass * g_class)
-{
- /* sinkpad */
- pngenc->sinkpad = gst_pad_new_from_static_template
- (&pngenc_sink_template, "sink");
- gst_pad_set_chain_function (pngenc->sinkpad, gst_pngenc_chain);
- /* gst_pad_set_link_function (pngenc->sinkpad, gst_pngenc_sinklink); */
- /* gst_pad_set_getcaps_function (pngenc->sinkpad, gst_pngenc_sink_getcaps); */
- gst_pad_set_setcaps_function (pngenc->sinkpad, gst_pngenc_setcaps);
- gst_element_add_pad (GST_ELEMENT (pngenc), pngenc->sinkpad);
-
- /* srcpad */
- pngenc->srcpad = gst_pad_new_from_static_template
- (&pngenc_src_template, "src");
- /* pngenc->srcpad = gst_pad_new ("src", GST_PAD_SRC); */
- /* gst_pad_set_getcaps_function (pngenc->srcpad, gst_pngenc_src_getcaps); */
- /* gst_pad_set_setcaps_function (pngenc->srcpad, gst_pngenc_setcaps); */
- gst_element_add_pad (GST_ELEMENT (pngenc), pngenc->srcpad);
-
- /* init settings */
- pngenc->png_struct_ptr = NULL;
- pngenc->png_info_ptr = NULL;
-
- pngenc->snapshot = DEFAULT_SNAPSHOT;
-/* pngenc->newmedia = FALSE; */
- pngenc->compression_level = DEFAULT_COMPRESSION_LEVEL;
-}
-
-static void
-user_flush_data (png_structp png_ptr G_GNUC_UNUSED)
-{
-}
-
-static void
-user_write_data (png_structp png_ptr, png_bytep data, png_uint_32 length)
-{
- GstPngEnc *pngenc;
-
- pngenc = (GstPngEnc *) png_get_io_ptr (png_ptr);
-
- if (pngenc->written + length >= GST_BUFFER_SIZE (pngenc->buffer_out)) {
- GST_ERROR_OBJECT (pngenc, "output buffer bigger than the input buffer!?");
- /* yuck */
- longjmp (pngenc->png_struct_ptr->jmpbuf, 1);
-
- /* never reached */
- return;
- }
-
- memcpy (GST_BUFFER_DATA (pngenc->buffer_out) + pngenc->written, data, length);
- pngenc->written += length;
-}
-
-static GstFlowReturn
-gst_pngenc_chain (GstPad * pad, GstBuffer * buf)
-{
- GstPngEnc *pngenc;
- gint row_index;
- png_byte *row_pointers[MAX_HEIGHT];
- GstFlowReturn ret = GST_FLOW_OK;
- GstBuffer *encoded_buf = NULL;
-
- pngenc = GST_PNGENC (gst_pad_get_parent (pad));
-
- GST_DEBUG_OBJECT (pngenc, "BEGINNING");
-
- /* initialize png struct stuff */
- pngenc->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
- (png_voidp) NULL, user_error_fn, user_warning_fn);
- if (pngenc->png_struct_ptr == NULL) {
- gst_buffer_unref (buf);
- GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL),
- ("Failed to initialize png structure"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-
- pngenc->png_info_ptr = png_create_info_struct (pngenc->png_struct_ptr);
- if (!pngenc->png_info_ptr) {
- gst_buffer_unref (buf);
- png_destroy_write_struct (&(pngenc->png_struct_ptr), (png_infopp) NULL);
- GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL),
- ("Failed to initialize the png info structure"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-
- /* non-0 return is from a longjmp inside of libpng */
- if (setjmp (pngenc->png_struct_ptr->jmpbuf) != 0) {
- gst_buffer_unref (buf);
- png_destroy_write_struct (&pngenc->png_struct_ptr, &pngenc->png_info_ptr);
- GST_ELEMENT_ERROR (pngenc, LIBRARY, FAILED, (NULL),
- ("returning from longjmp"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-
- png_set_filter (pngenc->png_struct_ptr, 0,
- PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE);
- png_set_compression_level (pngenc->png_struct_ptr, pngenc->compression_level);
-
- png_set_IHDR (pngenc->png_struct_ptr,
- pngenc->png_info_ptr,
- pngenc->width,
- pngenc->height,
- 8,
- (pngenc->bpp == 32) ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- png_set_write_fn (pngenc->png_struct_ptr, pngenc,
- (png_rw_ptr) user_write_data, user_flush_data);
-
- for (row_index = 0; row_index < pngenc->height; row_index++) {
- row_pointers[row_index] = GST_BUFFER_DATA (buf) +
- (row_index * pngenc->stride);
- }
-
- /* allocate the output buffer */
- pngenc->buffer_out =
- gst_buffer_new_and_alloc (pngenc->height * pngenc->stride);
- pngenc->written = 0;
-
- png_write_info (pngenc->png_struct_ptr, pngenc->png_info_ptr);
- png_write_image (pngenc->png_struct_ptr, row_pointers);
- png_write_end (pngenc->png_struct_ptr, NULL);
-
- encoded_buf = gst_buffer_create_sub (pngenc->buffer_out, 0, pngenc->written);
-
- png_destroy_info_struct (pngenc->png_struct_ptr, &pngenc->png_info_ptr);
- png_destroy_write_struct (&pngenc->png_struct_ptr, (png_infopp) NULL);
- gst_buffer_copy_metadata (encoded_buf, buf, GST_BUFFER_COPY_TIMESTAMPS);
- gst_buffer_unref (buf);
- gst_buffer_set_caps (encoded_buf, GST_PAD_CAPS (pngenc->srcpad));
-
- if ((ret = gst_pad_push (pngenc->srcpad, encoded_buf)) != GST_FLOW_OK)
- goto done;
-
- if (pngenc->snapshot) {
- GstEvent *event;
-
- GST_DEBUG_OBJECT (pngenc, "snapshot mode, sending EOS");
- /* send EOS event, since a frame has been pushed out */
- event = gst_event_new_eos ();
-
- gst_pad_push_event (pngenc->srcpad, event);
- ret = GST_FLOW_UNEXPECTED;
- }
-
-done:
- GST_DEBUG_OBJECT (pngenc, "END, ret:%d", ret);
-
- if (pngenc->buffer_out != NULL) {
- gst_buffer_unref (pngenc->buffer_out);
- pngenc->buffer_out = NULL;
- }
-
- gst_object_unref (pngenc);
- return ret;
-}
-
-
-static void
-gst_pngenc_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- GstPngEnc *pngenc;
-
- pngenc = GST_PNGENC (object);
-
- switch (prop_id) {
- case ARG_SNAPSHOT:
- g_value_set_boolean (value, pngenc->snapshot);
- break;
-/* case ARG_NEWMEDIA: */
-/* g_value_set_boolean (value, pngenc->newmedia); */
-/* break; */
- case ARG_COMPRESSION_LEVEL:
- g_value_set_uint (value, pngenc->compression_level);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-static void
-gst_pngenc_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
-{
- GstPngEnc *pngenc;
-
- pngenc = GST_PNGENC (object);
-
- switch (prop_id) {
- case ARG_SNAPSHOT:
- pngenc->snapshot = g_value_get_boolean (value);
- break;
-/* case ARG_NEWMEDIA: */
-/* pngenc->newmedia = g_value_get_boolean (value); */
-/* break; */
- case ARG_COMPRESSION_LEVEL:
- pngenc->compression_level = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/ext/libpng/gstpngenc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_PNGENC_H__
-#define __GST_PNGENC_H__
-
-#include <gst/gst.h>
-#include <png.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define GST_TYPE_PNGENC (gst_pngenc_get_type())
-#define GST_PNGENC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PNGENC,GstPngEnc))
-#define GST_PNGENC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PNGENC,GstPngEncClass))
-#define GST_IS_PNGENC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PNGENC))
-#define GST_IS_PNGENC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PNGENC))
-
-typedef struct _GstPngEnc GstPngEnc;
-typedef struct _GstPngEncClass GstPngEncClass;
-
-struct _GstPngEnc
-{
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
- GstBuffer *buffer_out;
- guint written;
-
- png_structp png_struct_ptr;
- png_infop png_info_ptr;
-
- gint width;
- gint height;
- gint bpp;
- gint stride;
- guint compression_level;
-
- gboolean snapshot;
- gboolean newmedia;
-};
-
-struct _GstPngEncClass
-{
- GstElementClass parent_class;
-};
-
-GType gst_pngenc_get_type(void);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __GST_PNGENC_H__ */
--- a/gst_plugins_good/group/bld.inf Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_good/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -6,8 +6,4 @@
PRJ_MMPFILES
gstwavparse.mmp
gstwavenc.mmp
-gstautodetect.mmp
-gstavi.mmp
gstqtmux.mmp
-gstqtdemux.mmp
-gstmpegaudioparse.mmp
--- a/gst_plugins_good/group/gstalaw.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-// Gstreamer.MMP
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-
-#include <platform_paths.hrh>
-
-TARGET libgstalaw.dll
-TARGETTYPE DLL
-UID 0x20004c47 0x0DE80A1D
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO __SYMBIAN32__
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ..
-USERINCLUDE ../gst/law
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/law
-SOURCE alaw.c
-SOURCE alaw-decode.c
-SOURCE alaw-encode.c
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-
-
--- a/gst_plugins_good/group/gstalpha.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-/*
-============================================================================
- Name : gstalpha.mmp
- Author :
- Copyright : Your copyright notice
- Description : This is the project specification file for alpha.
-============================================================================
-*/
-
-#include <platform_paths.hrh>
-TARGET libgstalpha.dll
-TARGETTYPE dll
-UID 0x1000008d 0x0B6AF79A
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO SYMBIAN
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ../../..
-USERINCLUDE ..
-USERINCLUDE ../gst/alpha
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/alpha
-SOURCE gstalpha.c
-
-LIBRARY libc.lib
-LIBRARY libm.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstriff.lib
-LIBRARY libgstcontroller.lib
-LIBRARY libgstvideo.lib
\ No newline at end of file
--- a/gst_plugins_good/group/gstalphacolor.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-/*
-============================================================================
- Name : alphacolor.mmp
- Author :
- Copyright : Your copyright notice
- Description : This is the project specification file for alpha.
-============================================================================
-*/
-#include <platform_paths.hrh>
-TARGET libgstalphacolor.dll
-TARGETTYPE dll
-UID 0x1000008d 0x0B6AF79B
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO SYMBIAN
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ../../..
-USERINCLUDE ..
-USERINCLUDE ../gst/alpha
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/alpha
-SOURCE gstalphacolor.c
-
-LIBRARY libc.lib
-LIBRARY libm.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstriff.lib
-LIBRARY libgstcontroller.lib
-LIBRARY libgstvideo.lib
\ No newline at end of file
--- a/gst_plugins_good/group/gstaudiofx.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-// Gstreamer.MMP
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-
-#include <platform_paths.hrh>
-
-TARGET libgstaudiofx.dll
-TARGETTYPE DLL
-UID 0x20004c49 0x0DE80A1F
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO __SYMBIAN32__
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ..
-USERINCLUDE ../gst/audiofx
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/audiofx
-SOURCE audioamplify.c
-
-SOURCE audiocheblimit.c
-SOURCE audiodynamic.c
-SOURCE audioecho.c
-SOURCE audiofirfilter.c
-SOURCE audiofx.c
-SOURCE audiofxbasefirfilter.c
-SOURCE audiofxbaseiirfilter.c
-SOURCE audioiirfilter.c
-SOURCE audioinvert.c
-SOURCE audiokaraoke.c
-SOURCE audiochebband.c
-SOURCE audiopanorama.c
-SOURCE audiowsinclimit.c
-SOURCE audiowsincband.c
-
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstcontroller.lib
-LIBRARY libgstaudio.lib
-LIBRARY libm.lib
-
--- a/gst_plugins_good/group/gstauparse.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-// Gstreamer.MMP
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-
-#include <platform_paths.hrh>
-
-TARGET libgstauparse.dll
-TARGETTYPE DLL
-UID 0x20004c46 0x0DE80A1C
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO __SYMBIAN32__
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ..
-USERINCLUDE ../gst/auparse
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-
-SOURCEPATH ../gst/auparse
-SOURCE gstauparse.c
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-
--- a/gst_plugins_good/group/gstautodetect.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-// gstautodetect.mmp
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-#include <platform_paths.hrh>
-
-TARGET libgstautodetect.dll
-TARGETTYPE DLL
-UID 0x1000008d 0x2001F446
-//TARGETTYPE STDDLL
-//UID 0x20004c45 0x0DE80A1D
-
-
-LANG SC
-CAPABILITY All -TCB
-VENDORID VID_DEFAULT
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO HAVE_CONFIG_H
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-USERINCLUDE ../
-
-
-
-SOURCEPATH ../gst/autodetect
-SOURCE gstautodetect.c
-SOURCE gstautoaudiosrc.c
-SOURCE gstautovideosrc.c
-SOURCE gstautoaudiosink.c
-SOURCE gstautovideosink.c
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-
-#ifdef WINSCW
-LIBRARY ewsd.lib //wsd solution
-#endif
-
-
-SMPSAFE
--- a/gst_plugins_good/group/gstavi.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-#include <platform_paths.hrh>
-
-TARGET libgstavi.dll
-TARGETTYPE DLL
-UID 0x20004c46 0x0DE80A1C
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO SYMBIAN
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ../../..
-USERINCLUDE ..
-USERINCLUDE ../gst/avi
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/avi
-SOURCE gstavi.c gstavimux.c gstavidemux.c gstavisubtitle.c
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstriff.lib
-
--- a/gst_plugins_good/group/gstjpeg.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-
-#include <platform_paths.hrh>
-
-TARGET libgstjpeg.dll
-TARGETTYPE DLL
-UID 0x1000008d 0x0FDE0317
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-USERINCLUDE ../ext/jpeg/.
-USERINCLUDE ../gst-libs/gst/.
-USERINCLUDE ../.
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SYSTEMINCLUDE /epoc32/include/jpeg-6b
-
-SOURCEPATH ../ext/jpeg
-SOURCE gstjpeg.c
-SOURCE gstjpegdec.c
-SOURCE gstjpegenc.c
-SOURCE gstsmokedec.c
-SOURCE gstsmokeenc.c
-SOURCE smokecodec.c
-
-LIBRARY euser.lib
-LIBRARY libc.lib libm.lib
-LIBRARY libgobject.lib libglib.lib
-LIBRARY libgstreamer.lib
-LIBRARY libjpeg.lib
-
-MACRO __SYMBIAN32__
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-EPOCSTACKSIZE 0x12000
\ No newline at end of file
--- a/gst_plugins_good/group/gstmpegaudioparse.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-#include <platform_paths.hrh>
-
-TARGET libgstmpegaudioparse.dll
-TARGETTYPE DLL
-UID 0x1000008d 0x10207C45
-CAPABILITY All -TCB
-VENDORID VID_DEFAULT
-LANG SC
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-
-MACRO HAVE_CONFIG_H
-
-
-USERINCLUDE ../gst/mpegaudioparse
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/mpegaudioparse
-SOURCE gstmpegaudioparse.c
-SOURCE gstxingmux.c
-SOURCE plugin.c
-
-LIBRARY euser.lib
-LIBRARY libc.lib
-LIBRARY libpthread.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgthread.lib
-
--- a/gst_plugins_good/group/gstmulaw.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-#include <platform_paths.hrh>
-
-TARGET libgstmulaw.dll
-TARGETTYPE DLL
-UID 0x20004c48 0x0DE80A1E
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO __SYMBIAN32__
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ..
-USERINCLUDE ../gst/law
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/law
-SOURCE mulaw.c
-SOURCE mulaw-conversion.c
-SOURCE mulaw-decode.c
-SOURCE mulaw-encode.c
-
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-
--- a/gst_plugins_good/group/gstpng.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-/*
-============================================================================
- Name : libgstpng.mmp
- Author :
- Copyright : Your copyright notice
- Description : This is the project specification file for libpng.
-============================================================================
-*/
-
-#include <platform_paths.hrh>
-
-TARGET libgstpng.dll
-TARGETTYPE dll
-UID 0x1000008d 0x011746FD
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO SYMBIAN
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ../../..
-USERINCLUDE ..
-USERINCLUDE ../ext/libpng
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-USERINCLUDE /epoc32/include/libpng
-
-SOURCEPATH ../ext/libpng
-SOURCE gstpng.c gstpngdec.c gstpngenc.c
-
-LIBRARY libc.lib
-LIBRARY libm.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstriff.lib
-LIBRARY libgstcontroller.lib
-LIBRARY libgstvideo.lib
-LIBRARY libpng.lib
\ No newline at end of file
--- a/gst_plugins_good/group/gstqtdemux.mmp Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-// Gstreamer.MMP
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Description:
-*
-*/
-
-
-#include <platform_paths.hrh>
-
-TARGET libgstqtdemux.dll
-TARGETTYPE DLL
-UID 0x20004c49 0x0DE80E1F
-
-#ifdef EKA2
-LANG SC
-CAPABILITY All -Tcb
-VENDORID VID_DEFAULT
-#endif
-
-#if !defined(__WINSCW__) && !defined(__WINS__)
-EpocAllowDllData
-#endif
-
-MACRO SYMBIAN
-MACRO HAVE_CONFIG_H
-MACRO __SYMBIAN32__
-
-USERINCLUDE ..
-USERINCLUDE ../gst/qtdemux
-USERINCLUDE ../gst-libs
-USERINCLUDE ../gst-libs/gst
-
-
-MW_LAYER_SYSTEMINCLUDE
-OS_LAYER_LIBC_SYSTEMINCLUDE
-OS_LAYER_GLIB_SYSTEMINCLUDE
-MW_LAYER_GSTREAMER_SYSTEMINCLUDE
-
-SOURCEPATH ../gst/qtdemux
-SOURCE quicktime.c gstrtpxqtdepay.c qtdemux.c qtdemux_types.c qtdemux_dump.c
-
-
-LIBRARY libc.lib
-LIBRARY libglib.lib
-LIBRARY libgobject.lib
-LIBRARY libgstreamer.lib
-LIBRARY libgstbase.lib
-LIBRARY libgstcontroller.lib
-LIBRARY libgstaudio.lib
-LIBRARY libm.lib libgstrtp.lib libgsttag.lib
-
--- a/gst_plugins_good/gst/alpha/gstalpha.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,930 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2007> Wim Taymans <wim.taymans@collabora.co.uk>
- * Copyright (C) <2007> Edward Hervey <edward.hervey@collabora.co.uk>
- * Copyright (C) <2007> Jan Schmidt <thaytan@noraisin.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/video/video.h>
-#include <gst/controller/gstcontroller.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define GST_TYPE_ALPHA \
- (gst_alpha_get_type())
-#define GST_ALPHA(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALPHA,GstAlpha))
-#define GST_ALPHA_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALPHA,GstAlphaClass))
-#define GST_IS_ALPHA(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALPHA))
-#define GST_IS_ALPHA_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALPHA))
-
-typedef struct _GstAlpha GstAlpha;
-typedef struct _GstAlphaClass GstAlphaClass;
-
-typedef enum
-{
- ALPHA_METHOD_SET,
- ALPHA_METHOD_GREEN,
- ALPHA_METHOD_BLUE,
- ALPHA_METHOD_CUSTOM,
-}
-GstAlphaMethod;
-
-GST_DEBUG_CATEGORY_STATIC (gst_alpha_debug);
-#define GST_CAT_DEFAULT gst_alpha_debug
-
-struct _GstAlpha
-{
- GstBaseTransform parent;
-
- /* caps */
- GstVideoFormat format;
- gint width, height;
- gboolean ayuv;
-
- gdouble alpha;
-
- guint target_r;
- guint target_g;
- guint target_b;
-
- GstAlphaMethod method;
-
- gfloat angle;
- gfloat noise_level;
- guint black_sensitivity;
- guint white_sensitivity;
-
- gfloat y; /* chroma color */
- gint8 cb, cr;
- gint8 kg;
- gfloat accept_angle_cos;
- gfloat accept_angle_sin;
- guint8 accept_angle_tg;
- guint8 accept_angle_ctg;
- guint8 one_over_kc;
- guint8 kfgy_scale;
-};
-
-struct _GstAlphaClass
-{
- GstBaseTransformClass parent_class;
-};
-
-/* elementfactory information */
-static const GstElementDetails gst_alpha_details =
-GST_ELEMENT_DETAILS ("Alpha filter",
- "Filter/Effect/Video",
- "Adds an alpha channel to video - uniform or via chroma-keying",
- "Wim Taymans <wim@fluendo.com>\n"
- "Edward Hervey <edward.hervey@collabora.co.uk>\n"
- "Jan Schmidt <thaytan@noraisin.net>");
-
-/* Alpha signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_METHOD ALPHA_METHOD_SET
-#define DEFAULT_ALPHA 1.0
-#define DEFAULT_TARGET_R 0
-#define DEFAULT_TARGET_G 255
-#define DEFAULT_TARGET_B 0
-#define DEFAULT_ANGLE 20.0
-#define DEFAULT_NOISE_LEVEL 2.0
-#define DEFAULT_BLACK_SENSITIVITY 100
-#define DEFAULT_WHITE_SENSITIVITY 100
-
-enum
-{
- PROP_0,
- PROP_METHOD,
- PROP_ALPHA,
- PROP_TARGET_R,
- PROP_TARGET_G,
- PROP_TARGET_B,
- PROP_ANGLE,
- PROP_NOISE_LEVEL,
- PROP_BLACK_SENSITIVITY,
- PROP_WHITE_SENSITIVITY,
- PROP_LAST
-};
-
-static GstStaticPadTemplate gst_alpha_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV"))
- );
-
-static GstStaticPadTemplate gst_alpha_sink_template =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_YUV ("I420")
- )
- );
-
-static gboolean gst_alpha_start (GstBaseTransform * trans);
-static gboolean gst_alpha_get_unit_size (GstBaseTransform * btrans,
- GstCaps * caps, guint * size);
-static GstCaps *gst_alpha_transform_caps (GstBaseTransform * btrans,
- GstPadDirection direction, GstCaps * caps);
-static gboolean gst_alpha_set_caps (GstBaseTransform * btrans,
- GstCaps * incaps, GstCaps * outcaps);
-static GstFlowReturn gst_alpha_transform (GstBaseTransform * btrans,
- GstBuffer * in, GstBuffer * out);
-
-static void gst_alpha_init_params (GstAlpha * alpha);
-
-static void gst_alpha_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_alpha_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GST_BOILERPLATE (GstAlpha, gst_alpha, GstBaseTransform,
- GST_TYPE_BASE_TRANSFORM);
-
-#define GST_TYPE_ALPHA_METHOD (gst_alpha_method_get_type())
-static GType
-gst_alpha_method_get_type (void)
-{
- static GType alpha_method_type = 0;
- static const GEnumValue alpha_method[] = {
- {ALPHA_METHOD_SET, "Set/adjust alpha channel", "set"},
- {ALPHA_METHOD_GREEN, "Chroma Key green", "green"},
- {ALPHA_METHOD_BLUE, "Chroma Key blue", "blue"},
- {ALPHA_METHOD_CUSTOM, "Chroma Key on target_r/g/b", "custom"},
- {0, NULL, NULL},
- };
-
- if (!alpha_method_type) {
- alpha_method_type = g_enum_register_static ("GstAlphaMethod", alpha_method);
- }
- return alpha_method_type;
-}
-
-static void
-gst_alpha_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details (element_class, &gst_alpha_details);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_alpha_sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_alpha_src_template));
-
- GST_DEBUG_CATEGORY_INIT (gst_alpha_debug, "alpha", 0,
- "alpha - Element for adding alpha channel to streams");
-}
-static void
-gst_alpha_class_init (GstAlphaClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseTransformClass *btrans_class;
-
- gobject_class = (GObjectClass *) klass;
- btrans_class = (GstBaseTransformClass *) klass;
-
- gobject_class->set_property = gst_alpha_set_property;
- gobject_class->get_property = gst_alpha_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_METHOD,
- g_param_spec_enum ("method", "Method",
- "How the alpha channels should be created", GST_TYPE_ALPHA_METHOD,
- DEFAULT_METHOD, (GParamFlags) G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ALPHA,
- g_param_spec_double ("alpha", "Alpha", "The value for the alpha channel",
- 0.0, 1.0, DEFAULT_ALPHA,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_R,
- g_param_spec_uint ("target_r", "Target Red", "The Red target", 0, 255,
- DEFAULT_TARGET_R,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_G,
- g_param_spec_uint ("target_g", "Target Green", "The Green target", 0, 255,
- DEFAULT_TARGET_G,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_B,
- g_param_spec_uint ("target_b", "Target Blue", "The Blue target", 0, 255,
- DEFAULT_TARGET_B,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ANGLE,
- g_param_spec_float ("angle", "Angle", "Size of the colorcube to change",
- 0.0, 90.0, DEFAULT_ANGLE,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NOISE_LEVEL,
- g_param_spec_float ("noise_level", "Noise Level", "Size of noise radius",
- 0.0, 64.0, DEFAULT_NOISE_LEVEL,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass),
- PROP_BLACK_SENSITIVITY, g_param_spec_uint ("black-sensitivity",
- "Black Sensitivity", "Sensitivity to dark colors", 0, 128,
- DEFAULT_BLACK_SENSITIVITY,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass),
- PROP_WHITE_SENSITIVITY, g_param_spec_uint ("white-sensitivity",
- "Sensitivity", "Sensitivity to bright colors", 0, 128,
- DEFAULT_WHITE_SENSITIVITY,
- (GParamFlags) G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
-
- btrans_class->start = GST_DEBUG_FUNCPTR (gst_alpha_start);
- btrans_class->transform = GST_DEBUG_FUNCPTR (gst_alpha_transform);
- btrans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_alpha_get_unit_size);
- btrans_class->transform_caps = GST_DEBUG_FUNCPTR (gst_alpha_transform_caps);
- btrans_class->set_caps = GST_DEBUG_FUNCPTR (gst_alpha_set_caps);
-}
-
-static void
-gst_alpha_init (GstAlpha * alpha, GstAlphaClass * klass)
-{
- alpha->alpha = DEFAULT_ALPHA;
- alpha->method = DEFAULT_METHOD;
- alpha->target_r = DEFAULT_TARGET_R;
- alpha->target_g = DEFAULT_TARGET_G;
- alpha->target_b = DEFAULT_TARGET_B;
- alpha->angle = DEFAULT_ANGLE;
- alpha->noise_level = DEFAULT_NOISE_LEVEL;
- alpha->black_sensitivity = DEFAULT_BLACK_SENSITIVITY;
- alpha->white_sensitivity = DEFAULT_WHITE_SENSITIVITY;
-}
-
-/* do we need this function? */
-static void
-gst_alpha_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAlpha *alpha;
-
- g_return_if_fail (GST_IS_ALPHA (object));
-
- alpha = GST_ALPHA (object);
-
- switch (prop_id) {
- case PROP_METHOD:
- alpha->method = g_value_get_enum (value);
- switch (alpha->method) {
- case ALPHA_METHOD_GREEN:
- alpha->target_r = 0;
- alpha->target_g = 255;
- alpha->target_b = 0;
- break;
- case ALPHA_METHOD_BLUE:
- alpha->target_r = 0;
- alpha->target_g = 0;
- alpha->target_b = 255;
- break;
- default:
- break;
- }
- gst_alpha_init_params (alpha);
- break;
- case PROP_ALPHA:
- alpha->alpha = g_value_get_double (value);
- break;
- case PROP_TARGET_R:
- alpha->target_r = g_value_get_uint (value);
- gst_alpha_init_params (alpha);
- break;
- case PROP_TARGET_G:
- alpha->target_g = g_value_get_uint (value);
- gst_alpha_init_params (alpha);
- break;
- case PROP_TARGET_B:
- alpha->target_b = g_value_get_uint (value);
- gst_alpha_init_params (alpha);
- break;
- case PROP_ANGLE:
- alpha->angle = g_value_get_float (value);
- gst_alpha_init_params (alpha);
- break;
- case PROP_NOISE_LEVEL:
- alpha->noise_level = g_value_get_float (value);
- gst_alpha_init_params (alpha);
- break;
- case PROP_BLACK_SENSITIVITY:
- alpha->black_sensitivity = g_value_get_uint (value);
- break;
- case PROP_WHITE_SENSITIVITY:
- alpha->white_sensitivity = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-static void
-gst_alpha_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstAlpha *alpha;
-
- g_return_if_fail (GST_IS_ALPHA (object));
-
- alpha = GST_ALPHA (object);
-
- switch (prop_id) {
- case PROP_METHOD:
- g_value_set_enum (value, alpha->method);
- break;
- case PROP_ALPHA:
- g_value_set_double (value, alpha->alpha);
- break;
- case PROP_TARGET_R:
- g_value_set_uint (value, alpha->target_r);
- break;
- case PROP_TARGET_G:
- g_value_set_uint (value, alpha->target_g);
- break;
- case PROP_TARGET_B:
- g_value_set_uint (value, alpha->target_b);
- break;
- case PROP_ANGLE:
- g_value_set_float (value, alpha->angle);
- break;
- case PROP_NOISE_LEVEL:
- g_value_set_float (value, alpha->noise_level);
- break;
- case PROP_BLACK_SENSITIVITY:
- g_value_set_uint (value, alpha->black_sensitivity);
- break;
- case PROP_WHITE_SENSITIVITY:
- g_value_set_uint (value, alpha->white_sensitivity);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-gst_alpha_get_unit_size (GstBaseTransform * btrans,
- GstCaps * caps, guint * size)
-{
- GstVideoFormat format;
- gint width, height;
-
- if (!gst_video_format_parse_caps (caps, &format, &width, &height))
- return FALSE;
-
- *size = gst_video_format_get_size (format, width, height);
-
- GST_DEBUG_OBJECT (btrans, "unit size = %d for format %d w %d height %d",
- *size, format, width, height);
-
- return TRUE;
-}
-
-static GstCaps *
-gst_alpha_transform_caps (GstBaseTransform * btrans,
- GstPadDirection direction, GstCaps * caps)
-{
- GstCaps *ret;
- GstStructure *structure;
- gint i;
-
- ret = gst_caps_copy (caps);
-
- /* When going from the SINK pad to the src, we just need to make sure the
- * format is AYUV */
- if (direction == GST_PAD_SINK) {
- for (i = 0; i < gst_caps_get_size (ret); i++) {
- structure = gst_caps_get_structure (ret, i);
- gst_structure_set (structure, "format",
- GST_TYPE_FOURCC, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'), NULL);
- }
- } else {
- GstCaps *ayuv_caps;
-
- /* In the other direction, prepend a copy of the caps with format AYUV,
- * and set the first to I420 */
- ayuv_caps = gst_caps_copy (ret);
-
- for (i = 0; i < gst_caps_get_size (ret); i++) {
- structure = gst_caps_get_structure (ret, i);
- gst_structure_set (structure, "format",
- GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), NULL);
- }
-
- gst_caps_append (ret, ayuv_caps);
- }
-
- gst_caps_do_simplify (ret);
-
- return ret;
-}
-
-static gboolean
-gst_alpha_set_caps (GstBaseTransform * btrans,
- GstCaps * incaps, GstCaps * outcaps)
-{
- GstAlpha *alpha = GST_ALPHA (btrans);
-
- if (!gst_video_format_parse_caps (incaps, &alpha->format,
- &alpha->width, &alpha->height))
- return FALSE;
-
- if (alpha->format == GST_VIDEO_FORMAT_AYUV)
- alpha->ayuv = TRUE;
- else
- alpha->ayuv = FALSE;
-
- return TRUE;
-}
-
-static void
-gst_alpha_set_ayuv (guint8 * src, guint8 * dest, gint width, gint height,
- gdouble alpha)
-{
- gint b_alpha = (gint) (alpha * 255);
- gint y, x;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- *dest++ = (*src++ * b_alpha) >> 8;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- }
- }
-}
-
-static void
-gst_alpha_set_i420 (guint8 * src, guint8 * dest, gint width, gint height,
- gdouble alpha)
-{
- gint b_alpha = (gint) (alpha * 255);
- guint8 *srcY;
- guint8 *srcU;
- guint8 *srcV;
- gint i, j;
- gint src_wrap, src_uv_wrap;
- gint y_stride, uv_stride;
- gboolean odd_width;
-
- y_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, width);
- uv_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, width);
-
- src_wrap = y_stride - width;
- src_uv_wrap = uv_stride - (width / 2);
-
- srcY = src;
- srcU = src + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420,
- 1, width, height);
- srcV = src + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420,
- 2, width, height);
-
- odd_width = (width % 2 != 0);
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width / 2; j++) {
- *dest++ = b_alpha;
- *dest++ = *srcY++;
- *dest++ = *srcU;
- *dest++ = *srcV;
- *dest++ = b_alpha;
- *dest++ = *srcY++;
- *dest++ = *srcU++;
- *dest++ = *srcV++;
- }
- /* Might have one odd column left to do */
- if (odd_width) {
- *dest++ = b_alpha;
- *dest++ = *srcY++;
- *dest++ = *srcU;
- *dest++ = *srcV;
- }
- if (i % 2 == 0) {
- srcU -= width / 2;
- srcV -= width / 2;
- } else {
- srcU += src_uv_wrap;
- srcV += src_uv_wrap;
- }
- srcY += src_wrap;
- }
-}
-
-static void
-gst_alpha_chroma_key_ayuv (guint8 * src, guint8 * dest, gint width, gint height,
- GstAlpha * alpha)
-{
- gint b_alpha;
- guint8 *src1;
- guint8 *dest1;
- gint i, j;
- gint x, z, u, v, y, a;
- gint tmp, tmp1;
- gint x1, y1;
- gint smin, smax;
-
- smin = 128 - alpha->black_sensitivity;
- smax = 128 + alpha->white_sensitivity;
-
- src1 = src;
- dest1 = dest;
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- a = *src1++ * (alpha->alpha);
- y = *src1++;
- u = *src1++ - 128;
- v = *src1++ - 128;
-
- if (y < smin || y > smax) {
- /* too dark or too bright, keep alpha */
- b_alpha = a;
- } else {
- /* Convert foreground to XZ coords where X direction is defined by
- the key color */
- tmp = ((short) u * alpha->cb + (short) v * alpha->cr) >> 7;
- x = CLAMP (tmp, -128, 127);
- tmp = ((short) v * alpha->cb - (short) u * alpha->cr) >> 7;
- z = CLAMP (tmp, -128, 127);
-
- /* WARNING: accept angle should never be set greater than "somewhat less
- than 90 degrees" to avoid dealing with negative/infinite tg. In reality,
- 80 degrees should be enough if foreground is reasonable. If this seems
- to be a problem, go to alternative ways of checking point position
- (scalar product or line equations). This angle should not be too small
- either to avoid infinite ctg (used to suppress foreground without use of
- division) */
-
- tmp = ((short) (x) * alpha->accept_angle_tg) >> 4;
- tmp = MIN (tmp, 127);
-
- if (abs (z) > tmp) {
- /* keep foreground Kfg = 0 */
- b_alpha = a;
- } else {
- /* Compute Kfg (implicitly) and Kbg, suppress foreground in XZ coord
- according to Kfg */
- tmp = ((short) (z) * alpha->accept_angle_ctg) >> 4;
- tmp = CLAMP (tmp, -128, 127);
- x1 = abs (tmp);
- y1 = z;
-
- tmp1 = x - x1;
- tmp1 = MAX (tmp1, 0);
- b_alpha = (((unsigned char) (tmp1) *
- (unsigned short) (alpha->one_over_kc)) / 2);
- b_alpha = 255 - CLAMP (b_alpha, 0, 255);
- b_alpha = (a * b_alpha) >> 8;
-
- tmp = ((unsigned short) (tmp1) * alpha->kfgy_scale) >> 4;
- tmp1 = MIN (tmp, 255);
-
- tmp = y - tmp1;
- y = MAX (tmp, 0);
-
- /* Convert suppressed foreground back to CbCr */
- tmp = ((char) (x1) * (short) (alpha->cb) -
- (char) (y1) * (short) (alpha->cr)) >> 7;
- u = CLAMP (tmp, -128, 127);
-
- tmp = ((char) (x1) * (short) (alpha->cr) +
- (char) (y1) * (short) (alpha->cb)) >> 7;
- v = CLAMP (tmp, -128, 127);
-
- /* Deal with noise. For now, a circle around the key color with
- radius of noise_level treated as exact key color. Introduces
- sharp transitions.
- */
- tmp = z * (short) (z) + (x - alpha->kg) * (short) (x - alpha->kg);
- tmp = MIN (tmp, 0xffff);
-
- if (tmp < alpha->noise_level * alpha->noise_level) {
- b_alpha = 0;
- }
- }
- }
-
- u += 128;
- v += 128;
-
- *dest1++ = b_alpha;
- *dest1++ = y;
- *dest1++ = u;
- *dest1++ = v;
- }
- }
-}
-
-static void
-gst_alpha_chromakey_row_i420 (GstAlpha * alpha, guint8 * dest1, guint8 * dest2,
- guint8 * srcY1, guint8 * srcY2, guint8 * srcU, guint8 * srcV, gint width)
-{
- gint xpos;
- gint b_alpha;
- gint x, z, u, v, y11, y12, y21, y22, a;
- gint tmp, tmp1;
- gint x1, y1;
- gint smin, smax;
-
- a = 255 * alpha->alpha;
- smin = 128 - alpha->black_sensitivity;
- smax = 128 + alpha->white_sensitivity;
-
- for (xpos = 0; xpos < width / 2; xpos++) {
- y11 = *srcY1++;
- y12 = *srcY1++;
- y21 = *srcY2++;
- y22 = *srcY2++;
- u = *srcU++ - 128;
- v = *srcV++ - 128;
-
- if (y11 < smin || y11 > smax ||
- y12 < smin || y12 > smax ||
- y21 < smin || y21 > smax || y22 < smin || y22 > smax) {
- /* too dark or too bright, make opaque */
- b_alpha = 255;
- } else {
- /* Convert foreground to XZ coords where X direction is defined by
- the key color */
- tmp = ((short) u * alpha->cb + (short) v * alpha->cr) >> 7;
- x = CLAMP (tmp, -128, 127);
- tmp = ((short) v * alpha->cb - (short) u * alpha->cr) >> 7;
- z = CLAMP (tmp, -128, 127);
-
- /* WARNING: accept angle should never be set greater than "somewhat less
- than 90 degrees" to avoid dealing with negative/infinite tg. In reality,
- 80 degrees should be enough if foreground is reasonable. If this seems
- to be a problem, go to alternative ways of checking point position
- (scalar product or line equations). This angle should not be too small
- either to avoid infinite ctg (used to suppress foreground without use of
- division) */
-
- tmp = ((short) (x) * alpha->accept_angle_tg) >> 4;
- tmp = MIN (tmp, 127);
-
- if (abs (z) > tmp) {
- /* keep foreground Kfg = 0 */
- b_alpha = 255;
- } else {
- /* Compute Kfg (implicitly) and Kbg, suppress foreground in XZ coord
- according to Kfg */
- tmp = ((short) (z) * alpha->accept_angle_ctg) >> 4;
- tmp = CLAMP (tmp, -128, 127);
- x1 = abs (tmp);
- y1 = z;
-
- tmp1 = x - x1;
- tmp1 = MAX (tmp1, 0);
- b_alpha = (((unsigned char) (tmp1) *
- (unsigned short) (alpha->one_over_kc)) / 2);
- b_alpha = 255 - CLAMP (b_alpha, 0, 255);
- b_alpha = (a * b_alpha) >> 8;
-
- tmp = ((unsigned short) (tmp1) * alpha->kfgy_scale) >> 4;
- tmp1 = MIN (tmp, 255);
-
- tmp = y11 - tmp1;
- y11 = MAX (tmp, 0);
- tmp = y12 - tmp1;
- y12 = MAX (tmp, 0);
- tmp = y21 - tmp1;
- y21 = MAX (tmp, 0);
- tmp = y22 - tmp1;
- y22 = MAX (tmp, 0);
-
- /* Convert suppressed foreground back to CbCr */
- tmp = ((char) (x1) * (short) (alpha->cb) -
- (char) (y1) * (short) (alpha->cr)) >> 7;
- u = CLAMP (tmp, -128, 127);
-
- tmp = ((char) (x1) * (short) (alpha->cr) +
- (char) (y1) * (short) (alpha->cb)) >> 7;
- v = CLAMP (tmp, -128, 127);
-
- /* Deal with noise. For now, a circle around the key color with
- radius of noise_level treated as exact key color. Introduces
- sharp transitions.
- */
- tmp = z * (short) (z) + (x - alpha->kg) * (short) (x - alpha->kg);
- tmp = MIN (tmp, 0xffff);
-
- if (tmp < alpha->noise_level * alpha->noise_level) {
- /* Uncomment this if you want total suppression within the noise circle */
- b_alpha = 0;
- }
- }
- }
-
- u += 128;
- v += 128;
-
- *dest1++ = b_alpha;
- *dest1++ = y11;
- *dest1++ = u;
- *dest1++ = v;
- *dest1++ = b_alpha;
- *dest1++ = y12;
- *dest1++ = u;
- *dest1++ = v;
-
- *dest2++ = b_alpha;
- *dest2++ = y21;
- *dest2++ = u;
- *dest2++ = v;
- *dest2++ = b_alpha;
- *dest2++ = y22;
- *dest2++ = u;
- *dest2++ = v;
- }
-}
-
-/* based on http://www.cs.utah.edu/~michael/chroma/
- */
-static void
-gst_alpha_chroma_key_i420 (guint8 * src, guint8 * dest, gint width, gint height,
- GstAlpha * alpha)
-{
- guint8 *srcY1, *srcY2, *srcU, *srcV;
- guint8 *dest1, *dest2;
- gint ypos;
- gint dest_stride, src_y_stride, src_uv_stride;
-
- dest_stride =
- gst_video_format_get_row_stride (GST_VIDEO_FORMAT_AYUV, 0, width);
- src_y_stride =
- gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, width);
- src_uv_stride =
- gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, width);
-
- srcY1 = src;
- srcY2 = src + src_y_stride;
-
- srcU = src + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420,
- 1, width, height);
- srcV = src + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420,
- 2, width, height);
-
- dest1 = dest;
- dest2 = dest + dest_stride;
-
- /* Redefine Y strides to skip 2 lines at a time ... */
- dest_stride *= 2;
- src_y_stride *= 2;
-
- for (ypos = 0; ypos < height / 2; ypos++) {
-
- gst_alpha_chromakey_row_i420 (alpha, dest1, dest2,
- srcY1, srcY2, srcU, srcV, width);
-
- dest1 += dest_stride;
- dest2 += dest_stride;
- srcY1 += src_y_stride;
- srcY2 += src_y_stride;
- srcU += src_uv_stride;
- srcV += src_uv_stride;
- }
-}
-
-static void
-gst_alpha_init_params (GstAlpha * alpha)
-{
- float kgl;
- float tmp;
- float tmp1, tmp2;
-
- alpha->y =
- 0.257 * alpha->target_r + 0.504 * alpha->target_g +
- 0.098 * alpha->target_b;
- tmp1 =
- -0.148 * alpha->target_r - 0.291 * alpha->target_g +
- 0.439 * alpha->target_b;
- tmp2 =
- 0.439 * alpha->target_r - 0.368 * alpha->target_g -
- 0.071 * alpha->target_b;
- kgl = sqrt (tmp1 * tmp1 + tmp2 * tmp2);
- alpha->cb = 127 * (tmp1 / kgl);
- alpha->cr = 127 * (tmp2 / kgl);
-
- alpha->accept_angle_cos = cos (M_PI * alpha->angle / 180);
- alpha->accept_angle_sin = sin (M_PI * alpha->angle / 180);
- tmp = 15 * tan (M_PI * alpha->angle / 180);
- tmp = MIN (tmp, 255);
- alpha->accept_angle_tg = tmp;
- tmp = 15 / tan (M_PI * alpha->angle / 180);
- tmp = MIN (tmp, 255);
- alpha->accept_angle_ctg = tmp;
- tmp = 1 / (kgl);
- alpha->one_over_kc = 255 * 2 * tmp - 255;
- tmp = 15 * (float) (alpha->y) / kgl;
- tmp = MIN (tmp, 255);
- alpha->kfgy_scale = tmp;
- alpha->kg = MIN (kgl, 127);
-}
-
-static gboolean
-gst_alpha_start (GstBaseTransform * btrans)
-{
- GstAlpha *alpha = GST_ALPHA (btrans);
-
- gst_alpha_init_params (alpha);
-
- return TRUE;
-}
-
-static GstFlowReturn
-gst_alpha_transform (GstBaseTransform * btrans, GstBuffer * in, GstBuffer * out)
-{
- GstAlpha *alpha = GST_ALPHA (btrans);
- gint width, height;
- GstClockTime timestamp;
-
- width = alpha->width;
- height = alpha->height;
-
- GST_BUFFER_TIMESTAMP (out) = GST_BUFFER_TIMESTAMP (in);
- GST_BUFFER_DURATION (out) = GST_BUFFER_DURATION (in);
- timestamp = gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME,
- GST_BUFFER_TIMESTAMP (in));
- GST_LOG ("Got stream time of %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
- if (GST_CLOCK_TIME_IS_VALID (timestamp))
- gst_object_sync_values (G_OBJECT (alpha), timestamp);
-
- switch (alpha->method) {
- case ALPHA_METHOD_SET:
- if (alpha->ayuv) {
- gst_alpha_set_ayuv (GST_BUFFER_DATA (in),
- GST_BUFFER_DATA (out), width, height, alpha->alpha);
- } else {
- gst_alpha_set_i420 (GST_BUFFER_DATA (in),
- GST_BUFFER_DATA (out), width, height, alpha->alpha);
- }
- break;
- case ALPHA_METHOD_GREEN:
- case ALPHA_METHOD_BLUE:
- case ALPHA_METHOD_CUSTOM:
- if (alpha->ayuv) {
- gst_alpha_chroma_key_ayuv (GST_BUFFER_DATA (in),
- GST_BUFFER_DATA (out), width, height, alpha);
- } else {
- gst_alpha_chroma_key_i420 (GST_BUFFER_DATA (in),
- GST_BUFFER_DATA (out), width, height, alpha);
- }
- break;
- default:
- break;
- }
-
- return GST_FLOW_OK;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- gst_controller_init (NULL, NULL);
-
- return gst_element_register (plugin, "alpha", GST_RANK_NONE, GST_TYPE_ALPHA);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "alpha",
- "adds an alpha channel to video - constant or via chroma-keying",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-
-#ifdef __SYMBIAN32__
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
-#endif
--- a/gst_plugins_good/gst/alpha/gstalphacolor.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-alphacolor
- *
- * The alphacolor element does memory-efficient (in-place) colourspace
- * conversion from RGBA to AYUV, preserving the alpha channel.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstalphacolor.h"
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-
-#include <string.h>
-
-GST_DEBUG_CATEGORY_STATIC (alpha_color_debug);
-#define GST_CAT_DEFAULT alpha_color_debug
-
-/* elementfactory information */
-static const GstElementDetails gst_alpha_color_details =
-GST_ELEMENT_DETAILS ("Alpha color filter",
- "Filter/Effect/Video",
- "RGBA to AYUV colorspace conversion preserving the alpha channel",
- "Wim Taymans <wim@fluendo.com>");
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA)
- );
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV"))
- );
-
-GST_BOILERPLATE (GstAlphaColor, gst_alpha_color, GstBaseTransform,
- GST_TYPE_BASE_TRANSFORM);
-
-static GstCaps *gst_alpha_color_transform_caps (GstBaseTransform * btrans,
- GstPadDirection direction, GstCaps * caps);
-static gboolean gst_alpha_color_set_caps (GstBaseTransform * btrans,
- GstCaps * incaps, GstCaps * outcaps);
-static GstFlowReturn gst_alpha_color_transform_ip (GstBaseTransform * btrans,
- GstBuffer * inbuf);
-
-static void
-gst_alpha_color_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details (element_class, &gst_alpha_color_details);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
-}
-
-static void
-gst_alpha_color_class_init (GstAlphaColorClass * klass)
-{
- GstBaseTransformClass *gstbasetransform_class;
-
- gstbasetransform_class = (GstBaseTransformClass *) klass;
-
- gstbasetransform_class->transform_caps =
- GST_DEBUG_FUNCPTR (gst_alpha_color_transform_caps);
- gstbasetransform_class->set_caps =
- GST_DEBUG_FUNCPTR (gst_alpha_color_set_caps);
- gstbasetransform_class->transform_ip =
- GST_DEBUG_FUNCPTR (gst_alpha_color_transform_ip);
-
- GST_DEBUG_CATEGORY_INIT (alpha_color_debug, "alphacolor", 0,
- "RGB->YUV colorspace conversion preserving the alpha channels");
-}
-
-static void
-gst_alpha_color_init (GstAlphaColor * alpha, GstAlphaColorClass * g_class)
-{
- GstBaseTransform *btrans = NULL;
-
- btrans = GST_BASE_TRANSFORM (alpha);
-
- btrans->always_in_place = TRUE;
-}
-
-static GstCaps *
-gst_alpha_color_transform_caps (GstBaseTransform * btrans,
- GstPadDirection direction, GstCaps * caps)
-{
- const GstCaps *tmpl_caps = NULL;
- GstCaps *result = NULL, *local_caps = NULL;
- guint i;
-
- local_caps = gst_caps_copy (caps);
-
- for (i = 0; i < gst_caps_get_size (local_caps); i++) {
- GstStructure *structure = gst_caps_get_structure (local_caps, i);
-
- /* Throw away the structure name and set it to transformed format */
- if (direction == GST_PAD_SINK) {
- gst_structure_set_name (structure, "video/x-raw-yuv");
- } else if (direction == GST_PAD_SRC) {
- gst_structure_set_name (structure, "video/x-raw-rgb");
- }
- /* Remove any specific parameter from the structure */
- gst_structure_remove_field (structure, "format");
- gst_structure_remove_field (structure, "endianness");
- gst_structure_remove_field (structure, "depth");
- gst_structure_remove_field (structure, "bpp");
- gst_structure_remove_field (structure, "red_mask");
- gst_structure_remove_field (structure, "green_mask");
- gst_structure_remove_field (structure, "blue_mask");
- gst_structure_remove_field (structure, "alpha_mask");
- }
-
- /* Get the appropriate template */
- if (direction == GST_PAD_SINK) {
- tmpl_caps = gst_static_pad_template_get_caps (&src_template);
- } else if (direction == GST_PAD_SRC) {
- tmpl_caps = gst_static_pad_template_get_caps (&sink_template);
- }
-
- /* Intersect with our template caps */
- result = gst_caps_intersect (local_caps, tmpl_caps);
-
- gst_caps_unref (local_caps);
- gst_caps_do_simplify (result);
-
- GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps, result);
-
- return result;
-}
-
-static gboolean
-gst_alpha_color_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
- GstCaps * outcaps)
-{
- GstAlphaColor *alpha;
- GstStructure *structure;
- gboolean ret;
- const GValue *fps;
- gint red_mask, alpha_mask;
- gint w, h, depth, bpp;
-
- alpha = GST_ALPHA_COLOR (btrans);
- structure = gst_caps_get_structure (incaps, 0);
-
- ret = gst_structure_get_int (structure, "width", &w);
- ret &= gst_structure_get_int (structure, "height", &h);
- fps = gst_structure_get_value (structure, "framerate");
- ret &= (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps));
- ret &= gst_structure_get_int (structure, "red_mask", &red_mask);
-
- /* make sure these are really full RGBA caps */
- ret &= gst_structure_get_int (structure, "alpha_mask", &alpha_mask);
- ret &= gst_structure_get_int (structure, "depth", &depth);
- ret &= gst_structure_get_int (structure, "bpp", &bpp);
-
- if (!ret || alpha_mask == 0 || red_mask == 0 || depth != 32 || bpp != 32) {
- GST_DEBUG_OBJECT (alpha, "incomplete or non-RGBA input caps!");
- return FALSE;
- }
-
- alpha->in_width = w;
- alpha->in_height = h;
- alpha->in_rgba = TRUE;
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
- if (red_mask != 0x000000ff)
-#else
- if (red_mask != 0xff000000)
-#endif
- alpha->in_rgba = FALSE;
-
- return TRUE;
-}
-
-static void
-transform_rgb (guint8 * data, gint size)
-{
- guint8 y, u, v;
-
- while (size > 0) {
- y = data[0] * 0.299 + data[1] * 0.587 + data[2] * 0.114 + 0;
- u = data[0] * -0.169 + data[1] * -0.332 + data[2] * 0.500 + 128;
- v = data[0] * 0.500 + data[1] * -0.419 + data[2] * -0.0813 + 128;
-
- data[0] = data[3];
- data[1] = y;
- data[2] = u;
- data[3] = v;
-
- data += 4;
- size -= 4;
- }
-}
-
-static void
-transform_bgr (guint8 * data, gint size)
-{
- guint8 y, u, v;
-
- while (size > 0) {
- y = data[2] * 0.299 + data[1] * 0.587 + data[0] * 0.114 + 0;
- u = data[2] * -0.169 + data[1] * -0.332 + data[0] * 0.500 + 128;
- v = data[2] * 0.500 + data[1] * -0.419 + data[0] * -0.0813 + 128;
-
- data[0] = data[3];
- data[1] = y;
- data[2] = u;
- data[3] = v;
-
- data += 4;
- size -= 4;
- }
-}
-
-static GstFlowReturn
-gst_alpha_color_transform_ip (GstBaseTransform * btrans, GstBuffer * inbuf)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- GstAlphaColor *alpha;
-
- alpha = GST_ALPHA_COLOR (btrans);
-
- /* Transform in place */
- if (alpha->in_rgba)
- transform_rgb (GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
- else
- transform_bgr (GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
-
- return ret;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, "alphacolor", GST_RANK_NONE,
- GST_TYPE_ALPHA_COLOR);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "alphacolor",
- "RGBA to AYUV colorspace conversion preserving the alpha channel",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-
-#ifdef __SYMBIAN32__
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
-#endif
--- a/gst_plugins_good/gst/alpha/gstalphacolor.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/* GStreamer alphacolor element
- * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _GST_ALPHA_COLOR_H_
-#define _GST_ALPHA_COLOR_H_
-
-#include <gst/base/gstbasetransform.h>
-
-#define GST_TYPE_ALPHA_COLOR \
- (gst_alpha_color_get_type())
-#define GST_ALPHA_COLOR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALPHA_COLOR,GstAlphaColor))
-#define GST_ALPHA_COLOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALPHA_COLOR,GstAlphaColorClass))
-#define GST_IS_ALPHA_COLOR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALPHA_COLOR))
-#define GST_IS_ALPHA_COLOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALPHA_COLOR))
-
-typedef struct _GstAlphaColor GstAlphaColor;
-typedef struct _GstAlphaColorClass GstAlphaColorClass;
-
-struct _GstAlphaColor
-{
- GstBaseTransform element;
-
- /*< private >*/
- /* caps */
- gint in_width, in_height;
- gboolean in_rgba;
- gint out_width, out_height;
-};
-
-struct _GstAlphaColorClass
-{
- GstBaseTransformClass parent_class;
-};
-
-GType gst_alpha_color_get_type (void);
-
-#endif /* _GST_ALPHA_COLOR_H_ */
--- a/gst_plugins_good/gst/audiofx/audioamplify.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,495 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audioamplify
- *
- * Amplifies an audio stream by a given factor and allows the selection of different clipping modes.
- * The difference between the clipping modes is best evaluated by testing.
- * <title>Example launch line</title>
- * <refsect2>
- * |[
- * gst-launch audiotestsrc wave=saw ! audioamplify amplification=1.5 ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audioamplify amplification=1.5 method=wrap-negative ! alsasink
- * gst-launch audiotestsrc wave=saw ! audioconvert ! audioamplify amplification=1.5 method=wrap-positive ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audioamplify.h"
-
-#define GST_CAT_DEFAULT gst_audio_amplify_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-static const GstElementDetails element_details =
-GST_ELEMENT_DETAILS ("Audio amplifier",
- "Filter/Effect/Audio",
- "Amplifies an audio stream by a given factor",
- "Sebastian Dröge <slomo@circular-chaos.org>");
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_AMPLIFICATION,
- PROP_CLIPPING_METHOD
-};
-
-enum
-{
- METHOD_CLIP = 0,
- METHOD_WRAP_NEGATIVE,
- METHOD_WRAP_POSITIVE,
- METHOD_NOCLIP,
- NUM_METHODS
-};
-
-#define GST_TYPE_AUDIO_AMPLIFY_CLIPPING_METHOD (gst_audio_amplify_clipping_method_get_type ())
-static GType
-gst_audio_amplify_clipping_method_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {METHOD_CLIP, "Normal clipping (default)", "clip"},
- {METHOD_WRAP_NEGATIVE,
- "Push overdriven values back from the opposite side",
- "wrap-negative"},
- {METHOD_WRAP_POSITIVE, "Push overdriven values back from the same side",
- "wrap-positive"},
- {METHOD_NOCLIP, "No clipping", "none"},
- {0, NULL, NULL}
- };
-
- /* FIXME 0.11: rename to GstAudioAmplifyClippingMethod */
- gtype = g_enum_register_static ("GstAudioPanoramaClippingMethod", values);
- }
- return gtype;
-}
-
-#define ALLOWED_CAPS \
- "audio/x-raw-int," \
- " depth=(int)8," \
- " width=(int)8," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-int," \
- " depth=(int)16," \
- " width=(int)16," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-int," \
- " depth=(int)32," \
- " width=(int)32," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-float," \
- " width=(int){32,64}," \
- " endianness=(int)BYTE_ORDER," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_amplify_debug, "audioamplify", 0, "audioamplify element");
-
-GST_BOILERPLATE_FULL (GstAudioAmplify, gst_audio_amplify, GstAudioFilter,
- GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static gboolean gst_audio_amplify_set_process_function (GstAudioAmplify *
- filter, gint clipping, gint format, gint width);
-static void gst_audio_amplify_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_amplify_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_audio_amplify_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-static GstFlowReturn gst_audio_amplify_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-
-#define MIN_gint8 G_MININT8
-#define MAX_gint8 G_MAXINT8
-#define MIN_gint16 G_MININT16
-#define MAX_gint16 G_MAXINT16
-#define MIN_gint32 G_MININT32
-#define MAX_gint32 G_MAXINT32
-
-#define MAKE_INT_FUNCS(type,largetype) \
-static void \
-gst_audio_amplify_transform_##type##_clip (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- largetype val = *d * filter->amplification; \
- *d++ = CLAMP (val, MIN_##type, MAX_##type); \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_wrap_negative (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- largetype val = *d * filter->amplification; \
- if (val > MAX_##type) \
- val = MIN_##type + (val - MIN_##type) % ((largetype) MAX_##type + 1 - \
- MIN_##type); \
- else if (val < MIN_##type) \
- val = MAX_##type - (MAX_##type - val) % ((largetype) MAX_##type + 1 - \
- MIN_##type); \
- *d++ = val; \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_wrap_positive (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- largetype val = *d * filter->amplification; \
- do { \
- if (val > MAX_##type) \
- val = MAX_##type - (val - MAX_##type); \
- else if (val < MIN_##type) \
- val = MIN_##type + (MIN_##type - val); \
- else \
- break; \
- } while (1); \
- *d++ = val; \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_noclip (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) \
- *d++ *= filter->amplification; \
-}
-
-#define MAKE_FLOAT_FUNCS(type) \
-static void \
-gst_audio_amplify_transform_##type##_clip (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- type val = *d* filter->amplification; \
- *d++ = CLAMP (val, -1.0, +1.0); \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_wrap_negative (GstAudioAmplify * \
- filter, void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- type val = *d * filter->amplification; \
- do { \
- if (val > 1.0) \
- val = -1.0 + (val - 1.0); \
- else if (val < -1.0) \
- val = 1.0 - (1.0 - val); \
- else \
- break; \
- } while (1); \
- *d++ = val; \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_wrap_positive (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) { \
- type val = *d* filter->amplification; \
- do { \
- if (val > 1.0) \
- val = 1.0 - (val - 1.0); \
- else if (val < -1.0) \
- val = -1.0 + (-1.0 - val); \
- else \
- break; \
- } while (1); \
- *d++ = val; \
- } \
-} \
-static void \
-gst_audio_amplify_transform_##type##_noclip (GstAudioAmplify * filter, \
- void * data, guint num_samples) \
-{ \
- type *d = data; \
- \
- while (num_samples--) \
- *d++ *= filter->amplification; \
-}
-
-/* *INDENT-OFF* */
-MAKE_INT_FUNCS (gint8,gint)
-MAKE_INT_FUNCS (gint16,gint)
-MAKE_INT_FUNCS (gint32,gint64)
-MAKE_FLOAT_FUNCS (gfloat)
-MAKE_FLOAT_FUNCS (gdouble)
-/* *INDENT-ON* */
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_amplify_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstCaps *caps;
-
- gst_element_class_set_details (element_class, &element_details);
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_amplify_class_init (GstAudioAmplifyClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_audio_amplify_set_property;
- gobject_class->get_property = gst_audio_amplify_get_property;
-
- g_object_class_install_property (gobject_class, PROP_AMPLIFICATION,
- g_param_spec_float ("amplification", "Amplification",
- "Factor of amplification", 0.0, G_MAXFLOAT,
- 1.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- /**
- * GstAudioAmplify:clipping-method
- *
- * Clipping method: clip mode set values higher than the maximum to the
- * maximum. The wrap-negative mode pushes those values back from the
- * opposite side, wrap-positive pushes them back from the same side.
- *
- **/
- g_object_class_install_property (gobject_class, PROP_CLIPPING_METHOD,
- g_param_spec_enum ("clipping-method", "Clipping method",
- "Selects how to handle values higher than the maximum",
- GST_TYPE_AUDIO_AMPLIFY_CLIPPING_METHOD, METHOD_CLIP,
- G_PARAM_READWRITE));
-
- GST_AUDIO_FILTER_CLASS (klass)->setup =
- GST_DEBUG_FUNCPTR (gst_audio_amplify_setup);
- GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_amplify_transform_ip);
-}
-
-static void
-gst_audio_amplify_init (GstAudioAmplify * filter, GstAudioAmplifyClass * klass)
-{
- filter->amplification = 1.0;
- gst_audio_amplify_set_process_function (filter, METHOD_CLIP,
- GST_BUFTYPE_LINEAR, 16);
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
- gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
-}
-
-static GstAudioAmplifyProcessFunc
-gst_audio_amplify_process_function (gint clipping, gint format, gint width)
-{
- static const struct process
- {
- gint format;
- gint width;
- gint clipping;
- GstAudioAmplifyProcessFunc func;
- } process[] = {
- {
- GST_BUFTYPE_FLOAT, 32, METHOD_CLIP,
- gst_audio_amplify_transform_gfloat_clip}, {
- GST_BUFTYPE_FLOAT, 32, METHOD_WRAP_NEGATIVE,
- gst_audio_amplify_transform_gfloat_wrap_negative}, {
- GST_BUFTYPE_FLOAT, 32, METHOD_WRAP_POSITIVE,
- gst_audio_amplify_transform_gfloat_wrap_positive}, {
- GST_BUFTYPE_FLOAT, 32, METHOD_NOCLIP,
- gst_audio_amplify_transform_gfloat_noclip}, {
- GST_BUFTYPE_FLOAT, 64, METHOD_CLIP,
- gst_audio_amplify_transform_gdouble_clip}, {
- GST_BUFTYPE_FLOAT, 64, METHOD_WRAP_NEGATIVE,
- gst_audio_amplify_transform_gdouble_wrap_negative}, {
- GST_BUFTYPE_FLOAT, 64, METHOD_WRAP_POSITIVE,
- gst_audio_amplify_transform_gdouble_wrap_positive}, {
- GST_BUFTYPE_FLOAT, 64, METHOD_NOCLIP,
- gst_audio_amplify_transform_gdouble_noclip}, {
- GST_BUFTYPE_LINEAR, 8, METHOD_CLIP, gst_audio_amplify_transform_gint8_clip}, {
- GST_BUFTYPE_LINEAR, 8, METHOD_WRAP_NEGATIVE,
- gst_audio_amplify_transform_gint8_wrap_negative}, {
- GST_BUFTYPE_LINEAR, 8, METHOD_WRAP_POSITIVE,
- gst_audio_amplify_transform_gint8_wrap_positive}, {
- GST_BUFTYPE_LINEAR, 8, METHOD_NOCLIP,
- gst_audio_amplify_transform_gint8_noclip}, {
- GST_BUFTYPE_LINEAR, 16, METHOD_CLIP,
- gst_audio_amplify_transform_gint16_clip}, {
- GST_BUFTYPE_LINEAR, 16, METHOD_WRAP_NEGATIVE,
- gst_audio_amplify_transform_gint16_wrap_negative}, {
- GST_BUFTYPE_LINEAR, 16, METHOD_WRAP_POSITIVE,
- gst_audio_amplify_transform_gint16_wrap_positive}, {
- GST_BUFTYPE_LINEAR, 16, METHOD_NOCLIP,
- gst_audio_amplify_transform_gint16_noclip}, {
- GST_BUFTYPE_LINEAR, 32, METHOD_CLIP,
- gst_audio_amplify_transform_gint32_clip}, {
- GST_BUFTYPE_LINEAR, 32, METHOD_WRAP_NEGATIVE,
- gst_audio_amplify_transform_gint32_wrap_negative}, {
- GST_BUFTYPE_LINEAR, 32, METHOD_WRAP_POSITIVE,
- gst_audio_amplify_transform_gint32_wrap_positive}, {
- GST_BUFTYPE_LINEAR, 32, METHOD_NOCLIP,
- gst_audio_amplify_transform_gint32_noclip}, {
- 0, 0, 0, NULL}
- };
- const struct process *p;
-
- for (p = process; p->func; p++)
- if (p->format == format && p->width == width && p->clipping == clipping)
- return p->func;
- return NULL;
-}
-
-static gboolean
-gst_audio_amplify_set_process_function (GstAudioAmplify * filter, gint
- clipping_method, gint format, gint width)
-{
- GstAudioAmplifyProcessFunc process;
-
- /* set processing function */
-
- process = gst_audio_amplify_process_function (clipping_method, format, width);
- if (!process) {
- GST_DEBUG ("wrong format");
- return FALSE;
- }
-
- filter->process = process;
- filter->clipping_method = clipping_method;
- filter->format = format;
- filter->width = width;
-
- return TRUE;
-}
-
-static void
-gst_audio_amplify_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (object);
-
- switch (prop_id) {
- case PROP_AMPLIFICATION:
- filter->amplification = g_value_get_float (value);
- gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter),
- filter->amplification == 1.0);
- break;
- case PROP_CLIPPING_METHOD:
- gst_audio_amplify_set_process_function (filter, g_value_get_enum (value),
- filter->format, filter->width);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_amplify_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (object);
-
- switch (prop_id) {
- case PROP_AMPLIFICATION:
- g_value_set_float (value, filter->amplification);
- break;
- case PROP_CLIPPING_METHOD:
- g_value_set_enum (value, filter->clipping_method);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-static gboolean
-gst_audio_amplify_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (base);
-
- return gst_audio_amplify_set_process_function (filter,
- filter->clipping_method, format->type, format->width);
-}
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_amplify_transform_ip (GstBaseTransform * base, GstBuffer * buf)
-{
- GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
- if (gst_base_transform_is_passthrough (base) ||
- G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
- return GST_FLOW_OK;
-
- filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audioamplify.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_AMPLIFY_H__
-#define __GST_AUDIO_AMPLIFY_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_AMPLIFY (gst_audio_amplify_get_type())
-#define GST_AUDIO_AMPLIFY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_AMPLIFY,GstAudioAmplify))
-#define GST_IS_AUDIO_AMPLIFY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_AMPLIFY))
-#define GST_AUDIO_AMPLIFY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_AMPLIFY,GstAudioAmplifyClass))
-#define GST_IS_AUDIO_AMPLIFY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_AMPLIFY))
-#define GST_AUDIO_AMPLIFY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_AMPLIFY,GstAudioAmplifyClass))
-typedef struct _GstAudioAmplify GstAudioAmplify;
-typedef struct _GstAudioAmplifyClass GstAudioAmplifyClass;
-
-typedef void (*GstAudioAmplifyProcessFunc) (GstAudioAmplify *, void *, guint);
-
-struct _GstAudioAmplify
-{
- GstAudioFilter audiofilter;
-
- gfloat amplification;
-
- /* < private > */
- GstAudioAmplifyProcessFunc process;
- gint clipping_method;
- gint format;
- gint width;
-};
-
-struct _GstAudioAmplifyClass
-{
- GstAudioFilterClass parent;
-};
-
-GType gst_audio_amplify_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_AMPLIFY_H__ */
--- a/gst_plugins_good/gst/audiofx/audiochebband.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,666 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * Chebyshev type 1 filter design based on
- * "The Scientist and Engineer's Guide to DSP", Chapter 20.
- * http://www.dspguide.com/
- *
- * For type 2 and Chebyshev filters in general read
- * http://en.wikipedia.org/wiki/Chebyshev_filter
- *
- * Transformation from lowpass to bandpass/bandreject:
- * http://docs.dewresearch.com/DspHelp/html/IDH_LinearSystems_LowpassToBandPassZ.htm
- * http://docs.dewresearch.com/DspHelp/html/IDH_LinearSystems_LowpassToBandStopZ.htm
- *
- */
-
-/**
- * SECTION:element-audiochebband
- *
- * Attenuates all frequencies outside (bandpass) or inside (bandreject) of a frequency
- * band. The number of poles and the ripple parameter control the rolloff.
- *
- * This element has the advantage over the windowed sinc bandpass and bandreject filter that it is
- * much faster and produces almost as good results. It's only disadvantages are the highly
- * non-linear phase and the slower rolloff compared to a windowed sinc filter with a large kernel.
- *
- * For type 1 the ripple parameter specifies how much ripple in dB is allowed in the passband, i.e.
- * some frequencies in the passband will be amplified by that value. A higher ripple value will allow
- * a faster rolloff.
- *
- * For type 2 the ripple parameter specifies the stopband attenuation. In the stopband the gain will
- * be at most this value. A lower ripple value will allow a faster rolloff.
- *
- * As a special case, a Chebyshev type 1 filter with no ripple is a Butterworth filter.
- *
- * <note>
- * Be warned that a too large number of poles can produce noise. The most poles are possible with
- * a cutoff frequency at a quarter of the sampling rate.
- * </note>
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc freq=1500 ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequenc=6000 poles=4 ! audioconvert ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiochebband mode=band-reject lower-frequency=1000 upper-frequency=4000 ripple=0.2 ! audioconvert ! alsasink
- * gst-launch audiotestsrc wave=white-noise ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequency=4000 type=2 ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include <math.h>
-
-#include "math_compat.h"
-
-#include "audiochebband.h"
-
-#define GST_CAT_DEFAULT gst_audio_cheb_band_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- PROP_0,
- PROP_MODE,
- PROP_TYPE,
- PROP_LOWER_FREQUENCY,
- PROP_UPPER_FREQUENCY,
- PROP_RIPPLE,
- PROP_POLES
-};
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_cheb_band_debug, "audiochebband", 0, "audiochebband element");
-
-GST_BOILERPLATE_FULL (GstAudioChebBand, gst_audio_cheb_band,
- GstAudioFXBaseIIRFilter, GST_TYPE_AUDIO_FX_BASE_IIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_cheb_band_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_audio_cheb_band_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_audio_cheb_band_finalize (GObject * object);
-
-static gboolean gst_audio_cheb_band_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-
-enum
-{
- MODE_BAND_PASS = 0,
- MODE_BAND_REJECT
-};
-
-#define GST_TYPE_AUDIO_CHEBYSHEV_FREQ_BAND_MODE (gst_audio_cheb_band_mode_get_type ())
-static GType
-gst_audio_cheb_band_mode_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {MODE_BAND_PASS, "Band pass (default)",
- "band-pass"},
- {MODE_BAND_REJECT, "Band reject",
- "band-reject"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioChebBandMode", values);
- }
- return gtype;
-}
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_cheb_band_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_set_details_simple (element_class,
- "Band pass & band reject filter", "Filter/Effect/Audio",
- "Chebyshev band pass and band reject filter",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_cheb_band_class_init (GstAudioChebBandClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_cheb_band_set_property;
- gobject_class->get_property = gst_audio_cheb_band_get_property;
- gobject_class->finalize = gst_audio_cheb_band_finalize;
-
- g_object_class_install_property (gobject_class, PROP_MODE,
- g_param_spec_enum ("mode", "Mode",
- "Low pass or high pass mode", GST_TYPE_AUDIO_CHEBYSHEV_FREQ_BAND_MODE,
- MODE_BAND_PASS,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_TYPE,
- g_param_spec_int ("type", "Type", "Type of the chebychev filter", 1, 2, 1,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- /* FIXME: Don't use the complete possible range but restrict the upper boundary
- * so automatically generated UIs can use a slider without */
- g_object_class_install_property (gobject_class, PROP_LOWER_FREQUENCY,
- g_param_spec_float ("lower-frequency", "Lower frequency",
- "Start frequency of the band (Hz)", 0.0, 100000.0,
- 0.0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_UPPER_FREQUENCY,
- g_param_spec_float ("upper-frequency", "Upper frequency",
- "Stop frequency of the band (Hz)", 0.0, 100000.0, 0.0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_RIPPLE,
- g_param_spec_float ("ripple", "Ripple", "Amount of ripple (dB)", 0.0,
- 200.0, 0.25,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- /* FIXME: What to do about this upper boundary? With a frequencies near
- * rate/4 32 poles are completely possible, with frequencies very low
- * or very high 16 poles already produces only noise */
- g_object_class_install_property (gobject_class, PROP_POLES,
- g_param_spec_int ("poles", "Poles",
- "Number of poles to use, will be rounded up to the next multiply of four",
- 4, 32, 4,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_cheb_band_setup);
-}
-
-static void
-gst_audio_cheb_band_init (GstAudioChebBand * filter,
- GstAudioChebBandClass * klass)
-{
- filter->lower_frequency = filter->upper_frequency = 0.0;
- filter->mode = MODE_BAND_PASS;
- filter->type = 1;
- filter->poles = 4;
- filter->ripple = 0.25;
-
- filter->lock = g_mutex_new ();
-}
-
-static void
-generate_biquad_coefficients (GstAudioChebBand * filter,
- gint p, gdouble * a0, gdouble * a1, gdouble * a2, gdouble * a3,
- gdouble * a4, gdouble * b1, gdouble * b2, gdouble * b3, gdouble * b4)
-{
- gint np = filter->poles / 2;
- gdouble ripple = filter->ripple;
-
- /* pole location in s-plane */
- gdouble rp, ip;
-
- /* zero location in s-plane */
- gdouble iz = 0.0;
-
- /* transfer function coefficients for the z-plane */
- gdouble x0, x1, x2, y1, y2;
- gint type = filter->type;
-
- /* Calculate pole location for lowpass at frequency 1 */
- {
- gdouble angle = (M_PI / 2.0) * (2.0 * p - 1) / np;
-
- rp = -sin (angle);
- ip = cos (angle);
- }
-
- /* If we allow ripple, move the pole from the unit
- * circle to an ellipse and keep cutoff at frequency 1 */
- if (ripple > 0 && type == 1) {
- gdouble es, vx;
-
- es = sqrt (pow (10.0, ripple / 10.0) - 1.0);
-
- vx = (1.0 / np) * asinh (1.0 / es);
- rp = rp * sinh (vx);
- ip = ip * cosh (vx);
- } else if (type == 2) {
- gdouble es, vx;
-
- es = sqrt (pow (10.0, ripple / 10.0) - 1.0);
- vx = (1.0 / np) * asinh (es);
- rp = rp * sinh (vx);
- ip = ip * cosh (vx);
- }
-
- /* Calculate inverse of the pole location to move from
- * type I to type II */
- if (type == 2) {
- gdouble mag2 = rp * rp + ip * ip;
-
- rp /= mag2;
- ip /= mag2;
- }
-
- /* Calculate zero location for frequency 1 on the
- * unit circle for type 2 */
- if (type == 2) {
- gdouble angle = M_PI / (np * 2.0) + ((p - 1) * M_PI) / (np);
- gdouble mag2;
-
- iz = cos (angle);
- mag2 = iz * iz;
- iz /= mag2;
- }
-
- /* Convert from s-domain to z-domain by
- * using the bilinear Z-transform, i.e.
- * substitute s by (2/t)*((z-1)/(z+1))
- * with t = 2 * tan(0.5).
- */
- if (type == 1) {
- gdouble t, m, d;
-
- t = 2.0 * tan (0.5);
- m = rp * rp + ip * ip;
- d = 4.0 - 4.0 * rp * t + m * t * t;
-
- x0 = (t * t) / d;
- x1 = 2.0 * x0;
- x2 = x0;
- y1 = (8.0 - 2.0 * m * t * t) / d;
- y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
- } else {
- gdouble t, m, d;
-
- t = 2.0 * tan (0.5);
- m = rp * rp + ip * ip;
- d = 4.0 - 4.0 * rp * t + m * t * t;
-
- x0 = (t * t * iz * iz + 4.0) / d;
- x1 = (-8.0 + 2.0 * iz * iz * t * t) / d;
- x2 = x0;
- y1 = (8.0 - 2.0 * m * t * t) / d;
- y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
- }
-
- /* Convert from lowpass at frequency 1 to either bandpass
- * or band reject.
- *
- * For bandpass substitute z^(-1) with:
- *
- * -2 -1
- * -z + alpha * z - beta
- * ----------------------------
- * -2 -1
- * beta * z - alpha * z + 1
- *
- * alpha = (2*a*b)/(1+b)
- * beta = (b-1)/(b+1)
- * a = cos((w1 + w0)/2) / cos((w1 - w0)/2)
- * b = tan(1/2) * cot((w1 - w0)/2)
- *
- * For bandreject substitute z^(-1) with:
- *
- * -2 -1
- * z - alpha * z + beta
- * ----------------------------
- * -2 -1
- * beta * z - alpha * z + 1
- *
- * alpha = (2*a)/(1+b)
- * beta = (1-b)/(1+b)
- * a = cos((w1 + w0)/2) / cos((w1 - w0)/2)
- * b = tan(1/2) * tan((w1 - w0)/2)
- *
- */
- {
- gdouble a, b, d;
- gdouble alpha, beta;
- gdouble w0 =
- 2.0 * M_PI * (filter->lower_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble w1 =
- 2.0 * M_PI * (filter->upper_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
-
- if (filter->mode == MODE_BAND_PASS) {
- a = cos ((w1 + w0) / 2.0) / cos ((w1 - w0) / 2.0);
- b = tan (1.0 / 2.0) / tan ((w1 - w0) / 2.0);
-
- alpha = (2.0 * a * b) / (1.0 + b);
- beta = (b - 1.0) / (b + 1.0);
-
- d = 1.0 + beta * (y1 - beta * y2);
-
- *a0 = (x0 + beta * (-x1 + beta * x2)) / d;
- *a1 = (alpha * (-2.0 * x0 + x1 + beta * x1 - 2.0 * beta * x2)) / d;
- *a2 =
- (-x1 - beta * beta * x1 + 2.0 * beta * (x0 + x2) +
- alpha * alpha * (x0 - x1 + x2)) / d;
- *a3 = (alpha * (x1 + beta * (-2.0 * x0 + x1) - 2.0 * x2)) / d;
- *a4 = (beta * (beta * x0 - x1) + x2) / d;
- *b1 = (alpha * (2.0 + y1 + beta * y1 - 2.0 * beta * y2)) / d;
- *b2 =
- (-y1 - beta * beta * y1 - alpha * alpha * (1.0 + y1 - y2) +
- 2.0 * beta * (-1.0 + y2)) / d;
- *b3 = (alpha * (y1 + beta * (2.0 + y1) - 2.0 * y2)) / d;
- *b4 = (-beta * beta - beta * y1 + y2) / d;
- } else {
- a = cos ((w1 + w0) / 2.0) / cos ((w1 - w0) / 2.0);
- b = tan (1.0 / 2.0) * tan ((w1 - w0) / 2.0);
-
- alpha = (2.0 * a) / (1.0 + b);
- beta = (1.0 - b) / (1.0 + b);
-
- d = -1.0 + beta * (beta * y2 + y1);
-
- *a0 = (-x0 - beta * x1 - beta * beta * x2) / d;
- *a1 = (alpha * (2.0 * x0 + x1 + beta * x1 + 2.0 * beta * x2)) / d;
- *a2 =
- (-x1 - beta * beta * x1 - 2.0 * beta * (x0 + x2) -
- alpha * alpha * (x0 + x1 + x2)) / d;
- *a3 = (alpha * (x1 + beta * (2.0 * x0 + x1) + 2.0 * x2)) / d;
- *a4 = (-beta * beta * x0 - beta * x1 - x2) / d;
- *b1 = (alpha * (-2.0 + y1 + beta * y1 + 2.0 * beta * y2)) / d;
- *b2 =
- -(y1 + beta * beta * y1 + 2.0 * beta * (-1.0 + y2) +
- alpha * alpha * (-1.0 + y1 + y2)) / d;
- *b3 = (alpha * (beta * (-2.0 + y1) + y1 + 2.0 * y2)) / d;
- *b4 = -(-beta * beta + beta * y1 + y2) / d;
- }
- }
-}
-
-static void
-generate_coefficients (GstAudioChebBand * filter)
-{
- if (GST_AUDIO_FILTER (filter)->format.rate == 0) {
- gdouble *a = g_new0 (gdouble, 1);
-
- a[0] = 1.0;
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, 1, NULL, 0);
- GST_LOG_OBJECT (filter, "rate was not set yet");
- return;
- }
-
- if (filter->upper_frequency <= filter->lower_frequency) {
- gdouble *a = g_new0 (gdouble, 1);
-
- a[0] = (filter->mode == MODE_BAND_PASS) ? 0.0 : 1.0;
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, 1, NULL, 0);
-
- GST_LOG_OBJECT (filter, "frequency band had no or negative dimension");
- return;
- }
-
- if (filter->upper_frequency > GST_AUDIO_FILTER (filter)->format.rate / 2) {
- filter->upper_frequency = GST_AUDIO_FILTER (filter)->format.rate / 2;
- GST_LOG_OBJECT (filter, "clipped upper frequency to nyquist frequency");
- }
-
- if (filter->lower_frequency < 0.0) {
- filter->lower_frequency = 0.0;
- GST_LOG_OBJECT (filter, "clipped lower frequency to 0.0");
- }
-
- /* Calculate coefficients for the chebyshev filter */
- {
- gint np = filter->poles;
- gdouble *a, *b;
- gint i, p;
-
- a = g_new0 (gdouble, np + 5);
- b = g_new0 (gdouble, np + 5);
-
- /* Calculate transfer function coefficients */
- a[4] = 1.0;
- b[4] = 1.0;
-
- for (p = 1; p <= np / 4; p++) {
- gdouble a0, a1, a2, a3, a4, b1, b2, b3, b4;
- gdouble *ta = g_new0 (gdouble, np + 5);
- gdouble *tb = g_new0 (gdouble, np + 5);
-
- generate_biquad_coefficients (filter, p, &a0, &a1, &a2, &a3, &a4, &b1,
- &b2, &b3, &b4);
-
- memcpy (ta, a, sizeof (gdouble) * (np + 5));
- memcpy (tb, b, sizeof (gdouble) * (np + 5));
-
- /* add the new coefficients for the new two poles
- * to the cascade by multiplication of the transfer
- * functions */
- for (i = 4; i < np + 5; i++) {
- a[i] =
- a0 * ta[i] + a1 * ta[i - 1] + a2 * ta[i - 2] + a3 * ta[i - 3] +
- a4 * ta[i - 4];
- b[i] =
- tb[i] - b1 * tb[i - 1] - b2 * tb[i - 2] - b3 * tb[i - 3] -
- b4 * tb[i - 4];
- }
- g_free (ta);
- g_free (tb);
- }
-
- /* Move coefficients to the beginning of the array
- * and multiply the b coefficients with -1 to move from
- * the transfer function's coefficients to the difference
- * equation's coefficients */
- b[4] = 0.0;
- for (i = 0; i <= np; i++) {
- a[i] = a[i + 4];
- b[i] = -b[i + 4];
- }
-
- /* Normalize to unity gain at frequency 0 and frequency
- * 0.5 for bandreject and unity gain at band center frequency
- * for bandpass */
- if (filter->mode == MODE_BAND_REJECT) {
- /* gain is sqrt(H(0)*H(0.5)) */
-
- gdouble gain1 =
- gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
- 1.0, 0.0);
- gdouble gain2 =
- gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
- -1.0, 0.0);
-
- gain1 = sqrt (gain1 * gain2);
-
- for (i = 0; i <= np; i++) {
- a[i] /= gain1;
- }
- } else {
- /* gain is H(wc), wc = center frequency */
-
- gdouble w1 =
- 2.0 * M_PI * (filter->lower_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble w2 =
- 2.0 * M_PI * (filter->upper_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble w0 = (w2 + w1) / 2.0;
- gdouble zr = cos (w0), zi = sin (w0);
- gdouble gain =
- gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1, zr,
- zi);
-
- for (i = 0; i <= np; i++) {
- a[i] /= gain;
- }
- }
-
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, np + 1, b, np + 1);
-
- GST_LOG_OBJECT (filter,
- "Generated IIR coefficients for the Chebyshev filter");
- GST_LOG_OBJECT (filter,
- "mode: %s, type: %d, poles: %d, lower-frequency: %.2f Hz, upper-frequency: %.2f Hz, ripple: %.2f dB",
- (filter->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject",
- filter->type, filter->poles, filter->lower_frequency,
- filter->upper_frequency, filter->ripple);
-
- GST_LOG_OBJECT (filter, "%.2f dB gain @ 0Hz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
- np + 1, 1.0, 0.0)));
- {
- gdouble w1 =
- 2.0 * M_PI * (filter->lower_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble w2 =
- 2.0 * M_PI * (filter->upper_frequency /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble w0 = (w2 + w1) / 2.0;
- gdouble zr, zi;
-
- zr = cos (w1);
- zi = sin (w1);
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
- b, np + 1, zr, zi)), (int) filter->lower_frequency);
- zr = cos (w0);
- zi = sin (w0);
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
- b, np + 1, zr, zi)),
- (int) ((filter->lower_frequency + filter->upper_frequency) / 2.0));
- zr = cos (w2);
- zi = sin (w2);
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
- b, np + 1, zr, zi)), (int) filter->upper_frequency);
- }
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
- np + 1, -1.0, 0.0)),
- GST_AUDIO_FILTER (filter)->format.rate / 2);
- }
-}
-
-static void
-gst_audio_cheb_band_finalize (GObject * object)
-{
- GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);
-
- g_mutex_free (filter->lock);
- filter->lock = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_cheb_band_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);
-
- switch (prop_id) {
- case PROP_MODE:
- g_mutex_lock (filter->lock);
- filter->mode = g_value_get_enum (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_TYPE:
- g_mutex_lock (filter->lock);
- filter->type = g_value_get_int (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_LOWER_FREQUENCY:
- g_mutex_lock (filter->lock);
- filter->lower_frequency = g_value_get_float (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_UPPER_FREQUENCY:
- g_mutex_lock (filter->lock);
- filter->upper_frequency = g_value_get_float (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_RIPPLE:
- g_mutex_lock (filter->lock);
- filter->ripple = g_value_get_float (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_POLES:
- g_mutex_lock (filter->lock);
- filter->poles = GST_ROUND_UP_4 (g_value_get_int (value));
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_cheb_band_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);
-
- switch (prop_id) {
- case PROP_MODE:
- g_value_set_enum (value, filter->mode);
- break;
- case PROP_TYPE:
- g_value_set_int (value, filter->type);
- break;
- case PROP_LOWER_FREQUENCY:
- g_value_set_float (value, filter->lower_frequency);
- break;
- case PROP_UPPER_FREQUENCY:
- g_value_set_float (value, filter->upper_frequency);
- break;
- case PROP_RIPPLE:
- g_value_set_float (value, filter->ripple);
- break;
- case PROP_POLES:
- g_value_set_int (value, filter->poles);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_cheb_band_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (base);
-
- generate_coefficients (filter);
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
--- a/gst_plugins_good/gst/audiofx/audiochebband.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_CHEB_BAND_H__
-#define __GST_AUDIO_CHEB_BAND_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-#include "audiofxbaseiirfilter.h"
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_CHEB_BAND (gst_audio_cheb_band_get_type())
-#define GST_AUDIO_CHEB_BAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_CHEB_BAND,GstAudioChebBand))
-#define GST_IS_AUDIO_CHEB_BAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_CHEB_BAND))
-#define GST_AUDIO_CHEB_BAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_CHEB_BAND,GstAudioChebBandClass))
-#define GST_IS_AUDIO_CHEB_BAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_CHEB_BAND))
-#define GST_AUDIO_CHEB_BAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_CHEB_BAND,GstAudioChebBandClass))
-typedef struct _GstAudioChebBand GstAudioChebBand;
-typedef struct _GstAudioChebBandClass GstAudioChebBandClass;
-
-struct _GstAudioChebBand
-{
- GstAudioFXBaseIIRFilter parent;
-
- gint mode;
- gint type;
- gint poles;
- gfloat lower_frequency;
- gfloat upper_frequency;
- gfloat ripple;
-
- /* < private > */
- GMutex *lock;
-};
-
-struct _GstAudioChebBandClass
-{
- GstAudioFXBaseIIRFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_cheb_band_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_CHEB_BAND_H__ */
--- a/gst_plugins_good/gst/audiofx/audiocheblimit.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,568 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * Chebyshev type 1 filter design based on
- * "The Scientist and Engineer's Guide to DSP", Chapter 20.
- * http://www.dspguide.com/
- *
- * For type 2 and Chebyshev filters in general read
- * http://en.wikipedia.org/wiki/Chebyshev_filter
- *
- */
-
-/**
- * SECTION:element-audiocheblimit
- *
- * Attenuates all frequencies above the cutoff frequency (low-pass) or all frequencies below the
- * cutoff frequency (high-pass). The number of poles and the ripple parameter control the rolloff.
- *
- * This element has the advantage over the windowed sinc lowpass and highpass filter that it is
- * much faster and produces almost as good results. It's only disadvantages are the highly
- * non-linear phase and the slower rolloff compared to a windowed sinc filter with a large kernel.
- *
- * For type 1 the ripple parameter specifies how much ripple in dB is allowed in the passband, i.e.
- * some frequencies in the passband will be amplified by that value. A higher ripple value will allow
- * a faster rolloff.
- *
- * For type 2 the ripple parameter specifies the stopband attenuation. In the stopband the gain will
- * be at most this value. A lower ripple value will allow a faster rolloff.
- *
- * As a special case, a Chebyshev type 1 filter with no ripple is a Butterworth filter.
- * </para>
- * <note><para>
- * Be warned that a too large number of poles can produce noise. The most poles are possible with
- * a cutoff frequency at a quarter of the sampling rate.
- * </para></note>
- * <para>
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc freq=1500 ! audioconvert ! audiocheblimit mode=low-pass cutoff=1000 poles=4 ! audioconvert ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiocheblimit mode=high-pass cutoff=400 ripple=0.2 ! audioconvert ! alsasink
- * gst-launch audiotestsrc wave=white-noise ! audioconvert ! audiocheblimit mode=low-pass cutoff=800 type=2 ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include <math.h>
-
-#include "math_compat.h"
-
-#include "audiocheblimit.h"
-
-#define GST_CAT_DEFAULT gst_audio_cheb_limit_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- PROP_0,
- PROP_MODE,
- PROP_TYPE,
- PROP_CUTOFF,
- PROP_RIPPLE,
- PROP_POLES
-};
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_cheb_limit_debug, "audiocheblimit", 0, "audiocheblimit element");
-
-GST_BOILERPLATE_FULL (GstAudioChebLimit,
- gst_audio_cheb_limit, GstAudioFXBaseIIRFilter,
- GST_TYPE_AUDIO_FX_BASE_IIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_cheb_limit_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_audio_cheb_limit_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_audio_cheb_limit_finalize (GObject * object);
-
-static gboolean gst_audio_cheb_limit_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-
-enum
-{
- MODE_LOW_PASS = 0,
- MODE_HIGH_PASS
-};
-
-#define GST_TYPE_AUDIO_CHEBYSHEV_FREQ_LIMIT_MODE (gst_audio_cheb_limit_mode_get_type ())
-static GType
-gst_audio_cheb_limit_mode_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {MODE_LOW_PASS, "Low pass (default)",
- "low-pass"},
- {MODE_HIGH_PASS, "High pass",
- "high-pass"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioChebLimitMode", values);
- }
- return gtype;
-}
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_cheb_limit_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_set_details_simple (element_class,
- "Low pass & high pass filter",
- "Filter/Effect/Audio",
- "Chebyshev low pass and high pass filter",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_cheb_limit_class_init (GstAudioChebLimitClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_cheb_limit_set_property;
- gobject_class->get_property = gst_audio_cheb_limit_get_property;
- gobject_class->finalize = gst_audio_cheb_limit_finalize;
-
- g_object_class_install_property (gobject_class, PROP_MODE,
- g_param_spec_enum ("mode", "Mode",
- "Low pass or high pass mode",
- GST_TYPE_AUDIO_CHEBYSHEV_FREQ_LIMIT_MODE, MODE_LOW_PASS,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_TYPE,
- g_param_spec_int ("type", "Type", "Type of the chebychev filter", 1, 2, 1,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- /* FIXME: Don't use the complete possible range but restrict the upper boundary
- * so automatically generated UIs can use a slider without */
- g_object_class_install_property (gobject_class, PROP_CUTOFF,
- g_param_spec_float ("cutoff", "Cutoff", "Cut off frequency (Hz)", 0.0,
- 100000.0, 0.0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_RIPPLE,
- g_param_spec_float ("ripple", "Ripple", "Amount of ripple (dB)", 0.0,
- 200.0, 0.25,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- /* FIXME: What to do about this upper boundary? With a cutoff frequency of
- * rate/4 32 poles are completely possible, with a cutoff frequency very low
- * or very high 16 poles already produces only noise */
- g_object_class_install_property (gobject_class, PROP_POLES,
- g_param_spec_int ("poles", "Poles",
- "Number of poles to use, will be rounded up to the next even number",
- 2, 32, 4,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_cheb_limit_setup);
-}
-
-static void
-gst_audio_cheb_limit_init (GstAudioChebLimit * filter,
- GstAudioChebLimitClass * klass)
-{
- filter->cutoff = 0.0;
- filter->mode = MODE_LOW_PASS;
- filter->type = 1;
- filter->poles = 4;
- filter->ripple = 0.25;
-
- filter->lock = g_mutex_new ();
-}
-
-static void
-generate_biquad_coefficients (GstAudioChebLimit * filter,
- gint p, gdouble * a0, gdouble * a1, gdouble * a2,
- gdouble * b1, gdouble * b2)
-{
- gint np = filter->poles;
- gdouble ripple = filter->ripple;
-
- /* pole location in s-plane */
- gdouble rp, ip;
-
- /* zero location in s-plane */
- gdouble iz = 0.0;
-
- /* transfer function coefficients for the z-plane */
- gdouble x0, x1, x2, y1, y2;
- gint type = filter->type;
-
- /* Calculate pole location for lowpass at frequency 1 */
- {
- gdouble angle = (M_PI / 2.0) * (2.0 * p - 1) / np;
-
- rp = -sin (angle);
- ip = cos (angle);
- }
-
- /* If we allow ripple, move the pole from the unit
- * circle to an ellipse and keep cutoff at frequency 1 */
- if (ripple > 0 && type == 1) {
- gdouble es, vx;
-
- es = sqrt (pow (10.0, ripple / 10.0) - 1.0);
-
- vx = (1.0 / np) * asinh (1.0 / es);
- rp = rp * sinh (vx);
- ip = ip * cosh (vx);
- } else if (type == 2) {
- gdouble es, vx;
-
- es = sqrt (pow (10.0, ripple / 10.0) - 1.0);
- vx = (1.0 / np) * asinh (es);
- rp = rp * sinh (vx);
- ip = ip * cosh (vx);
- }
-
- /* Calculate inverse of the pole location to convert from
- * type I to type II */
- if (type == 2) {
- gdouble mag2 = rp * rp + ip * ip;
-
- rp /= mag2;
- ip /= mag2;
- }
-
- /* Calculate zero location for frequency 1 on the
- * unit circle for type 2 */
- if (type == 2) {
- gdouble angle = M_PI / (np * 2.0) + ((p - 1) * M_PI) / (np);
- gdouble mag2;
-
- iz = cos (angle);
- mag2 = iz * iz;
- iz /= mag2;
- }
-
- /* Convert from s-domain to z-domain by
- * using the bilinear Z-transform, i.e.
- * substitute s by (2/t)*((z-1)/(z+1))
- * with t = 2 * tan(0.5).
- */
- if (type == 1) {
- gdouble t, m, d;
-
- t = 2.0 * tan (0.5);
- m = rp * rp + ip * ip;
- d = 4.0 - 4.0 * rp * t + m * t * t;
-
- x0 = (t * t) / d;
- x1 = 2.0 * x0;
- x2 = x0;
- y1 = (8.0 - 2.0 * m * t * t) / d;
- y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
- } else {
- gdouble t, m, d;
-
- t = 2.0 * tan (0.5);
- m = rp * rp + ip * ip;
- d = 4.0 - 4.0 * rp * t + m * t * t;
-
- x0 = (t * t * iz * iz + 4.0) / d;
- x1 = (-8.0 + 2.0 * iz * iz * t * t) / d;
- x2 = x0;
- y1 = (8.0 - 2.0 * m * t * t) / d;
- y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
- }
-
- /* Convert from lowpass at frequency 1 to either lowpass
- * or highpass.
- *
- * For lowpass substitute z^(-1) with:
- * -1
- * z - k
- * ------------
- * -1
- * 1 - k * z
- *
- * k = sin((1-w)/2) / sin((1+w)/2)
- *
- * For highpass substitute z^(-1) with:
- *
- * -1
- * -z - k
- * ------------
- * -1
- * 1 + k * z
- *
- * k = -cos((1+w)/2) / cos((1-w)/2)
- *
- */
- {
- gdouble k, d;
- gdouble omega =
- 2.0 * M_PI * (filter->cutoff / GST_AUDIO_FILTER (filter)->format.rate);
-
- if (filter->mode == MODE_LOW_PASS)
- k = sin ((1.0 - omega) / 2.0) / sin ((1.0 + omega) / 2.0);
- else
- k = -cos ((omega + 1.0) / 2.0) / cos ((omega - 1.0) / 2.0);
-
- d = 1.0 + y1 * k - y2 * k * k;
- *a0 = (x0 + k * (-x1 + k * x2)) / d;
- *a1 = (x1 + k * k * x1 - 2.0 * k * (x0 + x2)) / d;
- *a2 = (x0 * k * k - x1 * k + x2) / d;
- *b1 = (2.0 * k + y1 + y1 * k * k - 2.0 * y2 * k) / d;
- *b2 = (-k * k - y1 * k + y2) / d;
-
- if (filter->mode == MODE_HIGH_PASS) {
- *a1 = -*a1;
- *b1 = -*b1;
- }
- }
-}
-
-static void
-generate_coefficients (GstAudioChebLimit * filter)
-{
- if (GST_AUDIO_FILTER (filter)->format.rate == 0) {
- gdouble *a = g_new0 (gdouble, 1);
-
- a[0] = 1.0;
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, 1, NULL, 0);
-
- GST_LOG_OBJECT (filter, "rate was not set yet");
- return;
- }
-
- if (filter->cutoff >= GST_AUDIO_FILTER (filter)->format.rate / 2.0) {
- gdouble *a = g_new0 (gdouble, 1);
-
- a[0] = (filter->mode == MODE_LOW_PASS) ? 1.0 : 0.0;
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, 1, NULL, 0);
- GST_LOG_OBJECT (filter, "cutoff was higher than nyquist frequency");
- return;
- } else if (filter->cutoff <= 0.0) {
- gdouble *a = g_new0 (gdouble, 1);
-
- a[0] = (filter->mode == MODE_LOW_PASS) ? 0.0 : 1.0;
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, 1, NULL, 0);
- GST_LOG_OBJECT (filter, "cutoff is lower than zero");
- return;
- }
-
- /* Calculate coefficients for the chebyshev filter */
- {
- gint np = filter->poles;
- gdouble *a, *b;
- gint i, p;
-
- a = g_new0 (gdouble, np + 3);
- b = g_new0 (gdouble, np + 3);
-
- /* Calculate transfer function coefficients */
- a[2] = 1.0;
- b[2] = 1.0;
-
- for (p = 1; p <= np / 2; p++) {
- gdouble a0, a1, a2, b1, b2;
- gdouble *ta = g_new0 (gdouble, np + 3);
- gdouble *tb = g_new0 (gdouble, np + 3);
-
- generate_biquad_coefficients (filter, p, &a0, &a1, &a2, &b1, &b2);
-
- memcpy (ta, a, sizeof (gdouble) * (np + 3));
- memcpy (tb, b, sizeof (gdouble) * (np + 3));
-
- /* add the new coefficients for the new two poles
- * to the cascade by multiplication of the transfer
- * functions */
- for (i = 2; i < np + 3; i++) {
- a[i] = a0 * ta[i] + a1 * ta[i - 1] + a2 * ta[i - 2];
- b[i] = tb[i] - b1 * tb[i - 1] - b2 * tb[i - 2];
- }
- g_free (ta);
- g_free (tb);
- }
-
- /* Move coefficients to the beginning of the array
- * and multiply the b coefficients with -1 to move from
- * the transfer function's coefficients to the difference
- * equation's coefficients */
- b[2] = 0.0;
- for (i = 0; i <= np; i++) {
- a[i] = a[i + 2];
- b[i] = -b[i + 2];
- }
-
- /* Normalize to unity gain at frequency 0 for lowpass
- * and frequency 0.5 for highpass */
- {
- gdouble gain;
-
- if (filter->mode == MODE_LOW_PASS)
- gain =
- gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
- 1.0, 0.0);
- else
- gain =
- gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
- -1.0, 0.0);
-
- for (i = 0; i <= np; i++) {
- a[i] /= gain;
- }
- }
-
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (filter), a, np + 1, b, np + 1);
-
- GST_LOG_OBJECT (filter,
- "Generated IIR coefficients for the Chebyshev filter");
- GST_LOG_OBJECT (filter,
- "mode: %s, type: %d, poles: %d, cutoff: %.2f Hz, ripple: %.2f dB",
- (filter->mode == MODE_LOW_PASS) ? "low-pass" : "high-pass",
- filter->type, filter->poles, filter->cutoff, filter->ripple);
- GST_LOG_OBJECT (filter, "%.2f dB gain @ 0 Hz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
- np + 1, 1.0, 0.0)));
-
-#ifndef GST_DISABLE_GST_DEBUG
- {
- gdouble wc =
- 2.0 * M_PI * (filter->cutoff /
- GST_AUDIO_FILTER (filter)->format.rate);
- gdouble zr = cos (wc), zi = sin (wc);
-
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %d Hz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
- b, np + 1, zr, zi)), (int) filter->cutoff);
- }
-#endif
-
- GST_LOG_OBJECT (filter, "%.2f dB gain @ %d Hz",
- 20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
- np + 1, -1.0, 0.0)),
- GST_AUDIO_FILTER (filter)->format.rate / 2);
- }
-}
-
-static void
-gst_audio_cheb_limit_finalize (GObject * object)
-{
- GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (object);
-
- g_mutex_free (filter->lock);
- filter->lock = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_cheb_limit_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (object);
-
- switch (prop_id) {
- case PROP_MODE:
- g_mutex_lock (filter->lock);
- filter->mode = g_value_get_enum (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_TYPE:
- g_mutex_lock (filter->lock);
- filter->type = g_value_get_int (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_CUTOFF:
- g_mutex_lock (filter->lock);
- filter->cutoff = g_value_get_float (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_RIPPLE:
- g_mutex_lock (filter->lock);
- filter->ripple = g_value_get_float (value);
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- case PROP_POLES:
- g_mutex_lock (filter->lock);
- filter->poles = GST_ROUND_UP_2 (g_value_get_int (value));
- generate_coefficients (filter);
- g_mutex_unlock (filter->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_cheb_limit_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (object);
-
- switch (prop_id) {
- case PROP_MODE:
- g_value_set_enum (value, filter->mode);
- break;
- case PROP_TYPE:
- g_value_set_int (value, filter->type);
- break;
- case PROP_CUTOFF:
- g_value_set_float (value, filter->cutoff);
- break;
- case PROP_RIPPLE:
- g_value_set_float (value, filter->ripple);
- break;
- case PROP_POLES:
- g_value_set_int (value, filter->poles);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_cheb_limit_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (base);
-
- generate_coefficients (filter);
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
--- a/gst_plugins_good/gst/audiofx/audiocheblimit.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_CHEB_LIMIT_H__
-#define __GST_AUDIO_CHEB_LIMIT_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-#include "audiofxbaseiirfilter.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_CHEB_LIMIT (gst_audio_cheb_limit_get_type())
-#define GST_AUDIO_CHEB_LIMIT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_CHEB_LIMIT,GstAudioChebLimit))
-#define GST_IS_AUDIO_CHEB_LIMIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_CHEB_LIMIT))
-#define GST_AUDIO_CHEB_LIMIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_CHEB_LIMIT,GstAudioChebLimitClass))
-#define GST_IS_AUDIO_CHEB_LIMIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_CHEB_LIMIT))
-#define GST_AUDIO_CHEB_LIMIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_CHEB_LIMIT,GstAudioChebLimitClass))
-
-typedef struct _GstAudioChebLimit GstAudioChebLimit;
-typedef struct _GstAudioChebLimitClass GstAudioChebLimitClass;
-
-struct _GstAudioChebLimit
-{
- GstAudioFXBaseIIRFilter parent;
-
- gint mode;
- gint type;
- gint poles;
- gfloat cutoff;
- gfloat ripple;
-
- /* < private > */
- GMutex *lock;
-};
-
-struct _GstAudioChebLimitClass
-{
- GstAudioFXBaseIIRFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_cheb_limit_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_CHEB_LIMIT_H__ */
--- a/gst_plugins_good/gst/audiofx/audiodynamic.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,711 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audiodynamic
- *
- * This element can act as a compressor or expander. A compressor changes the
- * amplitude of all samples above a specific threshold with a specific ratio,
- * a expander does the same for all samples below a specific threshold. If
- * soft-knee mode is selected the ratio is applied smoothly.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc wave=saw ! audiodynamic characteristics=soft-knee mode=compressor threshold=0.5 rate=0.5 ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiodynamic characteristics=hard-knee mode=expander threshold=0.2 rate=4.0 ! alsasink
- * gst-launch audiotestsrc wave=saw ! audioconvert ! audiodynamic ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-/* TODO: Implement attack and release parameters */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiodynamic.h"
-
-#define GST_CAT_DEFAULT gst_audio_dynamic_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-static const GstElementDetails element_details =
-GST_ELEMENT_DETAILS ("Dynamic range controller",
- "Filter/Effect/Audio",
- "Compressor and Expander",
- "Sebastian Dröge <slomo@circular-chaos.org>");
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_CHARACTERISTICS,
- PROP_MODE,
- PROP_THRESHOLD,
- PROP_RATIO
-};
-
-#define ALLOWED_CAPS \
- "audio/x-raw-int," \
- " depth=(int)16," \
- " width=(int)16," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-float," \
- " width=(int)32," \
- " endianness=(int)BYTE_ORDER," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_dynamic_debug, "audiodynamic", 0, "audiodynamic element");
-
-GST_BOILERPLATE_FULL (GstAudioDynamic, gst_audio_dynamic, GstAudioFilter,
- GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static void gst_audio_dynamic_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_dynamic_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_audio_dynamic_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-static GstFlowReturn gst_audio_dynamic_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-
-static void
-gst_audio_dynamic_transform_hard_knee_compressor_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples);
-static void
-gst_audio_dynamic_transform_hard_knee_compressor_float (GstAudioDynamic *
- filter, gfloat * data, guint num_samples);
-static void
-gst_audio_dynamic_transform_soft_knee_compressor_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples);
-static void
-gst_audio_dynamic_transform_soft_knee_compressor_float (GstAudioDynamic *
- filter, gfloat * data, guint num_samples);
-static void gst_audio_dynamic_transform_hard_knee_expander_int (GstAudioDynamic
- * filter, gint16 * data, guint num_samples);
-static void
-gst_audio_dynamic_transform_hard_knee_expander_float (GstAudioDynamic * filter,
- gfloat * data, guint num_samples);
-static void gst_audio_dynamic_transform_soft_knee_expander_int (GstAudioDynamic
- * filter, gint16 * data, guint num_samples);
-static void
-gst_audio_dynamic_transform_soft_knee_expander_float (GstAudioDynamic * filter,
- gfloat * data, guint num_samples);
-
-static GstAudioDynamicProcessFunc process_functions[] = {
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_hard_knee_compressor_int,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_hard_knee_compressor_float,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_soft_knee_compressor_int,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_soft_knee_compressor_float,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_hard_knee_expander_int,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_hard_knee_expander_float,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_soft_knee_expander_int,
- (GstAudioDynamicProcessFunc)
- gst_audio_dynamic_transform_soft_knee_expander_float
-};
-
-enum
-{
- CHARACTERISTICS_HARD_KNEE = 0,
- CHARACTERISTICS_SOFT_KNEE
-};
-
-#define GST_TYPE_AUDIO_DYNAMIC_CHARACTERISTICS (gst_audio_dynamic_characteristics_get_type ())
-static GType
-gst_audio_dynamic_characteristics_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {CHARACTERISTICS_HARD_KNEE, "Hard Knee (default)",
- "hard-knee"},
- {CHARACTERISTICS_SOFT_KNEE, "Soft Knee (smooth)",
- "soft-knee"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioDynamicCharacteristics", values);
- }
- return gtype;
-}
-
-enum
-{
- MODE_COMPRESSOR = 0,
- MODE_EXPANDER
-};
-
-#define GST_TYPE_AUDIO_DYNAMIC_MODE (gst_audio_dynamic_mode_get_type ())
-static GType
-gst_audio_dynamic_mode_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {MODE_COMPRESSOR, "Compressor (default)",
- "compressor"},
- {MODE_EXPANDER, "Expander", "expander"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioDynamicMode", values);
- }
- return gtype;
-}
-
-static gboolean
-gst_audio_dynamic_set_process_function (GstAudioDynamic * filter)
-{
- gint func_index;
-
- func_index = (filter->mode == MODE_COMPRESSOR) ? 0 : 4;
- func_index += (filter->characteristics == CHARACTERISTICS_HARD_KNEE) ? 0 : 2;
- func_index +=
- (GST_AUDIO_FILTER (filter)->format.type == GST_BUFTYPE_FLOAT) ? 1 : 0;
-
- if (func_index >= 0 && func_index < 8) {
- filter->process = process_functions[func_index];
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_dynamic_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstCaps *caps;
-
- gst_element_class_set_details (element_class, &element_details);
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_dynamic_class_init (GstAudioDynamicClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_audio_dynamic_set_property;
- gobject_class->get_property = gst_audio_dynamic_get_property;
-
- g_object_class_install_property (gobject_class, PROP_CHARACTERISTICS,
- g_param_spec_enum ("characteristics", "Characteristics",
- "Selects whether the ratio should be applied smooth (soft-knee) "
- "or hard (hard-knee).",
- GST_TYPE_AUDIO_DYNAMIC_CHARACTERISTICS, CHARACTERISTICS_HARD_KNEE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_MODE,
- g_param_spec_enum ("mode", "Mode",
- "Selects whether the filter should work on loud samples (compressor) or"
- "quiet samples (expander).",
- GST_TYPE_AUDIO_DYNAMIC_MODE, MODE_COMPRESSOR, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_THRESHOLD,
- g_param_spec_float ("threshold", "Threshold",
- "Threshold until the filter is activated", 0.0, 1.0,
- 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_RATIO,
- g_param_spec_float ("ratio", "Ratio",
- "Ratio that should be applied", 0.0, G_MAXFLOAT,
- 1.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- GST_AUDIO_FILTER_CLASS (klass)->setup =
- GST_DEBUG_FUNCPTR (gst_audio_dynamic_setup);
- GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_dynamic_transform_ip);
-}
-
-static void
-gst_audio_dynamic_init (GstAudioDynamic * filter, GstAudioDynamicClass * klass)
-{
- filter->ratio = 1.0;
- filter->threshold = 0.0;
- filter->characteristics = CHARACTERISTICS_HARD_KNEE;
- filter->mode = MODE_COMPRESSOR;
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
- gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
-}
-
-static void
-gst_audio_dynamic_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioDynamic *filter = GST_AUDIO_DYNAMIC (object);
-
- switch (prop_id) {
- case PROP_CHARACTERISTICS:
- filter->characteristics = g_value_get_enum (value);
- gst_audio_dynamic_set_process_function (filter);
- break;
- case PROP_MODE:
- filter->mode = g_value_get_enum (value);
- gst_audio_dynamic_set_process_function (filter);
- break;
- case PROP_THRESHOLD:
- filter->threshold = g_value_get_float (value);
- break;
- case PROP_RATIO:
- filter->ratio = g_value_get_float (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_dynamic_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioDynamic *filter = GST_AUDIO_DYNAMIC (object);
-
- switch (prop_id) {
- case PROP_CHARACTERISTICS:
- g_value_set_enum (value, filter->characteristics);
- break;
- case PROP_MODE:
- g_value_set_enum (value, filter->mode);
- break;
- case PROP_THRESHOLD:
- g_value_set_float (value, filter->threshold);
- break;
- case PROP_RATIO:
- g_value_set_float (value, filter->ratio);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_dynamic_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioDynamic *filter = GST_AUDIO_DYNAMIC (base);
- gboolean ret = TRUE;
-
- ret = gst_audio_dynamic_set_process_function (filter);
-
- return ret;
-}
-
-static void
-gst_audio_dynamic_transform_hard_knee_compressor_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples)
-{
- glong val;
- glong thr_p = filter->threshold * G_MAXINT16;
- glong thr_n = filter->threshold * G_MININT16;
-
- /* Nothing to do for us if ratio is 1.0 or if the threshold
- * equals 1.0. */
- if (filter->threshold == 1.0 || filter->ratio == 1.0)
- return;
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val > thr_p) {
- val = thr_p + (val - thr_p) * filter->ratio;
- } else if (val < thr_n) {
- val = thr_n + (val - thr_n) * filter->ratio;
- }
- *data++ = (gint16) CLAMP (val, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_dynamic_transform_hard_knee_compressor_float (GstAudioDynamic *
- filter, gfloat * data, guint num_samples)
-{
- gdouble val, threshold = filter->threshold;
-
- /* Nothing to do for us if ratio == 1.0.
- * As float values can be above 1.0 we have to do something
- * if threshold is greater than 1.0. */
- if (filter->ratio == 1.0)
- return;
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val > threshold) {
- val = threshold + (val - threshold) * filter->ratio;
- } else if (val < -threshold) {
- val = -threshold + (val + threshold) * filter->ratio;
- }
- *data++ = (gfloat) val;
- }
-}
-
-static void
-gst_audio_dynamic_transform_soft_knee_compressor_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples)
-{
- glong val;
- glong thr_p = filter->threshold * G_MAXINT16;
- glong thr_n = filter->threshold * G_MININT16;
- gdouble a_p, b_p, c_p;
- gdouble a_n, b_n, c_n;
-
- /* Nothing to do for us if ratio is 1.0 or if the threshold
- * equals 1.0. */
- if (filter->threshold == 1.0 || filter->ratio == 1.0)
- return;
-
- /* We build a 2nd degree polynomial here for
- * values greater than threshold or small than
- * -threshold with:
- * f(t) = t, f'(t) = 1, f'(m) = r
- * =>
- * a = (1-r)/(2*(t-m))
- * b = (r*t - m)/(t-m)
- * c = t * (1 - b - a*t)
- * f(x) = ax^2 + bx + c
- */
-
- /* shouldn't happen because this would only be the case
- * for threshold == 1.0 which we catch above */
- g_assert (thr_p - G_MAXINT16 != 0);
- g_assert (thr_n - G_MININT != 0);
-
- a_p = (1 - filter->ratio) / (2 * (thr_p - G_MAXINT16));
- b_p = (filter->ratio * thr_p - G_MAXINT16) / (thr_p - G_MAXINT16);
- c_p = thr_p * (1 - b_p - a_p * thr_p);
- a_n = (1 - filter->ratio) / (2 * (thr_n - G_MININT16));
- b_n = (filter->ratio * thr_n - G_MININT16) / (thr_n - G_MININT16);
- c_n = thr_n * (1 - b_n - a_n * thr_n);
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val > thr_p) {
- val = a_p * val * val + b_p * val + c_p;
- } else if (val < thr_n) {
- val = a_n * val * val + b_n * val + c_n;
- }
- *data++ = (gint16) CLAMP (val, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_dynamic_transform_soft_knee_compressor_float (GstAudioDynamic *
- filter, gfloat * data, guint num_samples)
-{
- gdouble val;
- gdouble threshold = filter->threshold;
- gdouble a_p, b_p, c_p;
- gdouble a_n, b_n, c_n;
-
- /* Nothing to do for us if ratio == 1.0.
- * As float values can be above 1.0 we have to do something
- * if threshold is greater than 1.0. */
- if (filter->ratio == 1.0)
- return;
-
- /* We build a 2nd degree polynomial here for
- * values greater than threshold or small than
- * -threshold with:
- * f(t) = t, f'(t) = 1, f'(m) = r
- * =>
- * a = (1-r)/(2*(t-m))
- * b = (r*t - m)/(t-m)
- * c = t * (1 - b - a*t)
- * f(x) = ax^2 + bx + c
- */
-
- /* FIXME: If treshold is the same as the maximum
- * we need to raise it a bit to prevent
- * division by zero. */
- if (threshold == 1.0)
- threshold = 1.0 + 0.00001;
-
- a_p = (1.0 - filter->ratio) / (2.0 * (threshold - 1.0));
- b_p = (filter->ratio * threshold - 1.0) / (threshold - 1.0);
- c_p = threshold * (1.0 - b_p - a_p * threshold);
- a_n = (1.0 - filter->ratio) / (2.0 * (-threshold + 1.0));
- b_n = (-filter->ratio * threshold + 1.0) / (-threshold + 1.0);
- c_n = -threshold * (1.0 - b_n + a_n * threshold);
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val > 1.0) {
- val = 1.0 + (val - 1.0) * filter->ratio;
- } else if (val > threshold) {
- val = a_p * val * val + b_p * val + c_p;
- } else if (val < -1.0) {
- val = -1.0 + (val + 1.0) * filter->ratio;
- } else if (val < -threshold) {
- val = a_n * val * val + b_n * val + c_n;
- }
- *data++ = (gfloat) val;
- }
-}
-
-static void
-gst_audio_dynamic_transform_hard_knee_expander_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples)
-{
- glong val;
- glong thr_p = filter->threshold * G_MAXINT16;
- glong thr_n = filter->threshold * G_MININT16;
- gdouble zero_p, zero_n;
-
- /* Nothing to do for us here if threshold equals 0.0
- * or ratio equals 1.0 */
- if (filter->threshold == 0.0 || filter->ratio == 1.0)
- return;
-
- /* zero crossing of our function */
- if (filter->ratio != 0.0) {
- zero_p = thr_p - thr_p / filter->ratio;
- zero_n = thr_n - thr_n / filter->ratio;
- } else {
- zero_p = zero_n = 0.0;
- }
-
- if (zero_p < 0.0)
- zero_p = 0.0;
- if (zero_n > 0.0)
- zero_n = 0.0;
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val < thr_p && val > zero_p) {
- val = filter->ratio * val + thr_p * (1 - filter->ratio);
- } else if ((val <= zero_p && val > 0) || (val >= zero_n && val < 0)) {
- val = 0;
- } else if (val > thr_n && val < zero_n) {
- val = filter->ratio * val + thr_n * (1 - filter->ratio);
- }
- *data++ = (gint16) CLAMP (val, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_dynamic_transform_hard_knee_expander_float (GstAudioDynamic * filter,
- gfloat * data, guint num_samples)
-{
- gdouble val, threshold = filter->threshold, zero;
-
- /* Nothing to do for us here if threshold equals 0.0
- * or ratio equals 1.0 */
- if (filter->threshold == 0.0 || filter->ratio == 1.0)
- return;
-
- /* zero crossing of our function */
- if (filter->ratio != 0.0)
- zero = threshold - threshold / filter->ratio;
- else
- zero = 0.0;
-
- if (zero < 0.0)
- zero = 0.0;
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val < threshold && val > zero) {
- val = filter->ratio * val + threshold * (1.0 - filter->ratio);
- } else if ((val <= zero && val > 0.0) || (val >= -zero && val < 0.0)) {
- val = 0.0;
- } else if (val > -threshold && val < -zero) {
- val = filter->ratio * val - threshold * (1.0 - filter->ratio);
- }
- *data++ = (gfloat) val;
- }
-}
-
-static void
-gst_audio_dynamic_transform_soft_knee_expander_int (GstAudioDynamic * filter,
- gint16 * data, guint num_samples)
-{
- glong val;
- glong thr_p = filter->threshold * G_MAXINT16;
- glong thr_n = filter->threshold * G_MININT16;
- gdouble zero_p, zero_n;
- gdouble a_p, b_p, c_p;
- gdouble a_n, b_n, c_n;
-
- /* Nothing to do for us here if threshold equals 0.0
- * or ratio equals 1.0 */
- if (filter->threshold == 0.0 || filter->ratio == 1.0)
- return;
-
- /* zero crossing of our function */
- zero_p = (thr_p * (filter->ratio - 1.0)) / (1.0 + filter->ratio);
- zero_n = (thr_n * (filter->ratio - 1.0)) / (1.0 + filter->ratio);
-
- if (zero_p < 0.0)
- zero_p = 0.0;
- if (zero_n > 0.0)
- zero_n = 0.0;
-
- /* shouldn't happen as this would only happen
- * with threshold == 0.0 */
- g_assert (thr_p != 0);
- g_assert (thr_n != 0);
-
- /* We build a 2n degree polynomial here for values between
- * 0 and threshold or 0 and -threshold with:
- * f(t) = t, f'(t) = 1, f(z) = 0, f'(z) = r
- * z between 0 and t
- * =>
- * a = (1 - r^2) / (4 * t)
- * b = (1 + r^2) / 2
- * c = t * (1.0 - b - a*t)
- * f(x) = ax^2 + bx + c */
- a_p = (1.0 - filter->ratio * filter->ratio) / (4.0 * thr_p);
- b_p = (1.0 + filter->ratio * filter->ratio) / 2.0;
- c_p = thr_p * (1.0 - b_p - a_p * thr_p);
- a_n = (1.0 - filter->ratio * filter->ratio) / (4.0 * thr_n);
- b_n = (1.0 + filter->ratio * filter->ratio) / 2.0;
- c_n = thr_n * (1.0 - b_n - a_n * thr_n);
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val < thr_p && val > zero_p) {
- val = a_p * val * val + b_p * val + c_p;
- } else if ((val <= zero_p && val > 0) || (val >= zero_n && val < 0)) {
- val = 0;
- } else if (val > thr_n && val < zero_n) {
- val = a_n * val * val + b_n * val + c_n;
- }
- *data++ = (gint16) CLAMP (val, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_dynamic_transform_soft_knee_expander_float (GstAudioDynamic * filter,
- gfloat * data, guint num_samples)
-{
- gdouble val;
- gdouble threshold = filter->threshold;
- gdouble zero;
- gdouble a_p, b_p, c_p;
- gdouble a_n, b_n, c_n;
-
- /* Nothing to do for us here if threshold equals 0.0
- * or ratio equals 1.0 */
- if (filter->threshold == 0.0 || filter->ratio == 1.0)
- return;
-
- /* zero crossing of our function */
- zero = (threshold * (filter->ratio - 1.0)) / (1.0 + filter->ratio);
-
- if (zero < 0.0)
- zero = 0.0;
-
- /* shouldn't happen as this only happens with
- * threshold == 0.0 */
- g_assert (threshold != 0.0);
-
- /* We build a 2n degree polynomial here for values between
- * 0 and threshold or 0 and -threshold with:
- * f(t) = t, f'(t) = 1, f(z) = 0, f'(z) = r
- * z between 0 and t
- * =>
- * a = (1 - r^2) / (4 * t)
- * b = (1 + r^2) / 2
- * c = t * (1.0 - b - a*t)
- * f(x) = ax^2 + bx + c */
- a_p = (1.0 - filter->ratio * filter->ratio) / (4.0 * threshold);
- b_p = (1.0 + filter->ratio * filter->ratio) / 2.0;
- c_p = threshold * (1.0 - b_p - a_p * threshold);
- a_n = (1.0 - filter->ratio * filter->ratio) / (-4.0 * threshold);
- b_n = (1.0 + filter->ratio * filter->ratio) / 2.0;
- c_n = -threshold * (1.0 - b_n + a_n * threshold);
-
- for (; num_samples; num_samples--) {
- val = *data;
-
- if (val < threshold && val > zero) {
- val = a_p * val * val + b_p * val + c_p;
- } else if ((val <= zero && val > 0.0) || (val >= -zero && val < 0.0)) {
- val = 0.0;
- } else if (val > -threshold && val < -zero) {
- val = a_n * val * val + b_n * val + c_n;
- }
- *data++ = (gfloat) val;
- }
-}
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_dynamic_transform_ip (GstBaseTransform * base, GstBuffer * buf)
-{
- GstAudioDynamic *filter = GST_AUDIO_DYNAMIC (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
- if (gst_base_transform_is_passthrough (base) ||
- G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
- return GST_FLOW_OK;
-
- filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audiodynamic.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_DYNAMIC_H__
-#define __GST_AUDIO_DYNAMIC_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_DYNAMIC (gst_audio_dynamic_get_type())
-#define GST_AUDIO_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_DYNAMIC,GstAudioDynamic))
-#define GST_IS_AUDIO_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_DYNAMIC))
-#define GST_AUDIO_DYNAMIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_DYNAMIC,GstAudioDynamicClass))
-#define GST_IS_AUDIO_DYNAMIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_DYNAMIC))
-#define GST_AUDIO_DYNAMIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_DYNAMIC,GstAudioDynamicClass))
-typedef struct _GstAudioDynamic GstAudioDynamic;
-typedef struct _GstAudioDynamicClass GstAudioDynamicClass;
-
-typedef void (*GstAudioDynamicProcessFunc) (GstAudioDynamic *, guint8 *, guint);
-
-struct _GstAudioDynamic
-{
- GstAudioFilter audiofilter;
-
- gfloat degree;
-
- /* < private > */
- GstAudioDynamicProcessFunc process;
- gint characteristics;
- gint mode;
- gfloat threshold;
- gfloat ratio;
-};
-
-struct _GstAudioDynamicClass
-{
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_dynamic_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_DYNAMIC_H__ */
--- a/gst_plugins_good/gst/audiofx/audioecho.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,391 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audioecho
- * @Since: 0.10.14
- *
- * audioecho adds an echo or (simple) reverb effect to an audio stream. The echo
- * delay, intensity and the percentage of feedback can be configured.
- *
- * For getting an echo effect you have to set the delay to a larger value,
- * for example 200ms and more. Everything below will result in a simple
- * reverb effect, which results in a slightly metallic sound.
- *
- * Use the max-delay property to set the maximum amount of delay that
- * will be used. This can only be set before going to the PAUSED or PLAYING
- * state and will be set to the current delay by default.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch filesrc location="melo1.ogg" ! audioconvert ! audioecho delay=500000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
- * gst-launch filesrc location="melo1.ogg" ! decodebin ! audioconvert ! audioecho delay=50000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audioecho.h"
-
-#define GST_CAT_DEFAULT gst_audio_echo_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- PROP_0,
- PROP_DELAY,
- PROP_MAX_DELAY,
- PROP_INTENSITY,
- PROP_FEEDBACK
-};
-
-#define ALLOWED_CAPS \
- "audio/x-raw-float," \
- " width=(int) { 32, 64 }, " \
- " endianness=(int)BYTE_ORDER," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_echo_debug, "audioecho", 0, "audioecho element");
-
-GST_BOILERPLATE_FULL (GstAudioEcho, gst_audio_echo, GstAudioFilter,
- GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static void gst_audio_echo_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_echo_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_audio_echo_finalize (GObject * object);
-
-static gboolean gst_audio_echo_setup (GstAudioFilter * self,
- GstRingBufferSpec * format);
-static gboolean gst_audio_echo_stop (GstBaseTransform * base);
-static GstFlowReturn gst_audio_echo_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-
-static void gst_audio_echo_transform_float (GstAudioEcho * self,
- gfloat * data, guint num_samples);
-static void gst_audio_echo_transform_double (GstAudioEcho * self,
- gdouble * data, guint num_samples);
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_echo_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstCaps *caps;
-
- gst_element_class_set_details_simple (element_class, "Audio echo",
- "Filter/Effect/Audio",
- "Adds an echo or reverb effect to an audio stream",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_echo_class_init (GstAudioEchoClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstBaseTransformClass *basetransform_class = (GstBaseTransformClass *) klass;
- GstAudioFilterClass *audioself_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_echo_set_property;
- gobject_class->get_property = gst_audio_echo_get_property;
- gobject_class->finalize = gst_audio_echo_finalize;
-
- g_object_class_install_property (gobject_class, PROP_DELAY,
- g_param_spec_uint64 ("delay", "Delay",
- "Delay of the echo in nanoseconds", 1, G_MAXUINT64,
- 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_MAX_DELAY,
- g_param_spec_uint64 ("max-delay", "Maximum Delay",
- "Maximum delay of the echo in nanoseconds"
- " (can't be changed in PLAYING or PAUSED state)",
- 1, G_MAXUINT64, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_INTENSITY,
- g_param_spec_float ("intensity", "Intensity",
- "Intensity of the echo", 0.0, 1.0,
- 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_FEEDBACK,
- g_param_spec_float ("feedback", "Feedback",
- "Amount of feedback", 0.0, 1.0,
- 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- | GST_PARAM_CONTROLLABLE));
-
- audioself_class->setup = GST_DEBUG_FUNCPTR (gst_audio_echo_setup);
- basetransform_class->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_echo_transform_ip);
- basetransform_class->stop = GST_DEBUG_FUNCPTR (gst_audio_echo_stop);
-}
-
-static void
-gst_audio_echo_init (GstAudioEcho * self, GstAudioEchoClass * klass)
-{
- self->delay = 1;
- self->max_delay = 1;
- self->intensity = 0.0;
- self->feedback = 0.0;
-
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (self), TRUE);
-}
-
-static void
-gst_audio_echo_finalize (GObject * object)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (object);
-
- g_free (self->buffer);
- self->buffer = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_echo_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (object);
-
- switch (prop_id) {
- case PROP_DELAY:{
- guint64 max_delay, delay;
-
- GST_BASE_TRANSFORM_LOCK (self);
- delay = g_value_get_uint64 (value);
- max_delay = self->max_delay;
-
- if (delay > max_delay && GST_STATE (self) > GST_STATE_READY) {
- GST_WARNING_OBJECT (self, "New delay (%" GST_TIME_FORMAT ") "
- "is larger than maximum delay (%" GST_TIME_FORMAT ")",
- GST_TIME_ARGS (delay), GST_TIME_ARGS (max_delay));
- self->delay = max_delay;
- } else {
- self->delay = delay;
- self->max_delay = MAX (delay, max_delay);
- }
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
- break;
- case PROP_MAX_DELAY:{
- guint64 max_delay, delay;
-
- GST_BASE_TRANSFORM_LOCK (self);
- max_delay = g_value_get_uint64 (value);
- delay = self->delay;
-
- if (GST_STATE (self) > GST_STATE_READY) {
- GST_ERROR_OBJECT (self, "Can't change maximum delay in"
- " PLAYING or PAUSED state");
- } else {
- self->delay = delay;
- self->max_delay = max_delay;
- }
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
- break;
- case PROP_INTENSITY:{
- GST_BASE_TRANSFORM_LOCK (self);
- self->intensity = g_value_get_float (value);
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
- break;
- case PROP_FEEDBACK:{
- GST_BASE_TRANSFORM_LOCK (self);
- self->feedback = g_value_get_float (value);
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_echo_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (object);
-
- switch (prop_id) {
- case PROP_DELAY:
- GST_BASE_TRANSFORM_LOCK (self);
- g_value_set_uint64 (value, self->delay);
- GST_BASE_TRANSFORM_UNLOCK (self);
- break;
- case PROP_MAX_DELAY:
- GST_BASE_TRANSFORM_LOCK (self);
- g_value_set_uint64 (value, self->max_delay);
- GST_BASE_TRANSFORM_UNLOCK (self);
- break;
- case PROP_INTENSITY:
- GST_BASE_TRANSFORM_LOCK (self);
- g_value_set_float (value, self->intensity);
- GST_BASE_TRANSFORM_UNLOCK (self);
- break;
- case PROP_FEEDBACK:
- GST_BASE_TRANSFORM_LOCK (self);
- g_value_set_float (value, self->feedback);
- GST_BASE_TRANSFORM_UNLOCK (self);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_echo_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (base);
- gboolean ret = TRUE;
-
- if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
- self->process = (GstAudioEchoProcessFunc)
- gst_audio_echo_transform_float;
- else if (format->type == GST_BUFTYPE_FLOAT && format->width == 64)
- self->process = (GstAudioEchoProcessFunc)
- gst_audio_echo_transform_double;
- else
- ret = FALSE;
-
- g_free (self->buffer);
- self->buffer = NULL;
- self->buffer_pos = 0;
- self->buffer_size = 0;
- self->buffer_size_frames = 0;
-
- return ret;
-}
-
-static gboolean
-gst_audio_echo_stop (GstBaseTransform * base)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (base);
-
- g_free (self->buffer);
- self->buffer = NULL;
- self->buffer_pos = 0;
- self->buffer_size = 0;
- self->buffer_size_frames = 0;
-
- return TRUE;
-}
-
-#define TRANSFORM_FUNC(name, type) \
-static void \
-gst_audio_echo_transform_##name (GstAudioEcho * self, \
- type * data, guint num_samples) \
-{ \
- type *buffer = (type *) self->buffer; \
- guint channels = GST_AUDIO_FILTER (self)->format.channels; \
- guint rate = GST_AUDIO_FILTER (self)->format.rate; \
- guint i, j; \
- guint echo_index = self->buffer_size_frames - self->delay_frames; \
- gdouble echo_off = ((((gdouble) self->delay) * rate) / GST_SECOND) - self->delay_frames; \
- \
- if (echo_off < 0.0) \
- echo_off = 0.0; \
- \
- num_samples /= channels; \
- \
- for (i = 0; i < num_samples; i++) { \
- guint echo0_index = ((echo_index + self->buffer_pos) % self->buffer_size_frames) * channels; \
- guint echo1_index = ((echo_index + self->buffer_pos +1) % self->buffer_size_frames) * channels; \
- guint rbout_index = (self->buffer_pos % self->buffer_size_frames) * channels; \
- for (j = 0; j < channels; j++) { \
- gdouble in = data[i*channels + j]; \
- gdouble echo0 = buffer[echo0_index + j]; \
- gdouble echo1 = buffer[echo1_index + j]; \
- gdouble echo = echo0 + (echo1-echo0)*echo_off; \
- type out = in + self->intensity * echo; \
- \
- data[i*channels + j] = out; \
- \
- buffer[rbout_index + j] = in + self->feedback * echo; \
- } \
- self->buffer_pos = (self->buffer_pos + 1) % self->buffer_size_frames; \
- } \
-}
-
-TRANSFORM_FUNC (float, gfloat);
-TRANSFORM_FUNC (double, gdouble);
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
-{
- GstAudioEcho *self = GST_AUDIO_ECHO (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (self)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (self), GST_BUFFER_TIMESTAMP (buf));
-
- if (self->buffer == NULL) {
- guint width, rate, channels;
-
- width = GST_AUDIO_FILTER (self)->format.width / 8;
- rate = GST_AUDIO_FILTER (self)->format.rate;
- channels = GST_AUDIO_FILTER (self)->format.channels;
-
- self->delay_frames =
- MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);
- self->buffer_size_frames =
- MAX (gst_util_uint64_scale (self->max_delay, rate, GST_SECOND), 1);
-
- self->buffer_size = self->buffer_size_frames * width * channels;
- self->buffer = g_try_malloc0 (self->buffer_size);
- self->buffer_pos = 0;
-
- if (self->buffer == NULL) {
- GST_ERROR_OBJECT (self, "Failed to allocate %u bytes", self->buffer_size);
- return GST_FLOW_ERROR;
- }
- }
-
- self->process (self, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audioecho.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_ECHO_H__
-#define __GST_AUDIO_ECHO_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_ECHO (gst_audio_echo_get_type())
-#define GST_AUDIO_ECHO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_ECHO,GstAudioEcho))
-#define GST_IS_AUDIO_ECHO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_ECHO))
-#define GST_AUDIO_ECHO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_ECHO,GstAudioEchoClass))
-#define GST_IS_AUDIO_ECHO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_ECHO))
-#define GST_AUDIO_ECHO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_ECHO,GstAudioEchoClass))
-typedef struct _GstAudioEcho GstAudioEcho;
-typedef struct _GstAudioEchoClass GstAudioEchoClass;
-
-typedef void (*GstAudioEchoProcessFunc) (GstAudioEcho *, guint8 *, guint);
-
-struct _GstAudioEcho
-{
- GstAudioFilter audiofilter;
-
- guint64 delay;
- guint64 max_delay;
- gfloat intensity;
- gfloat feedback;
-
- /* < private > */
- GstAudioEchoProcessFunc process;
- guint delay_frames;
- guint8 *buffer;
- guint buffer_pos;
- guint buffer_size;
- guint buffer_size_frames;
-};
-
-struct _GstAudioEchoClass
-{
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_echo_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_ECHO_H__ */
--- a/gst_plugins_good/gst/audiofx/audiofirfilter.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-/**
- * SECTION:element-audiofirfilter
- *
- * audiofirfilter implements a generic audio <ulink url="http://en.wikipedia.org/wiki/Finite_impulse_response">FIR filter</ulink>. Before usage the
- * "kernel" property has to be set to the filter kernel that should be
- * used and the "latency" property has to be set to the latency (in samples)
- * that is introduced by the filter kernel. Setting a latency of n samples
- * will lead to the first n samples being dropped from the output and
- * n samples added to the end.
- *
- * The filter kernel describes the impulse response of the filter. To
- * calculate the frequency response of the filter you have to calculate
- * the Fourier Transform of the impulse response.
- *
- * To change the filter kernel whenever the sampling rate changes the
- * "rate-changed" signal can be used. This should be done for most
- * FIR filters as they're depending on the sampling rate.
- *
- * <refsect2>
- * <title>Example application</title>
- * |[
- * <xi:include xmlns:xi="http://www.w3.org/2003/XInclude" parse="text" href="../../../../tests/examples/audiofx/firfilter-example.c" />
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiofirfilter.h"
-
-#define GST_CAT_DEFAULT gst_audio_fir_filter_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- SIGNAL_RATE_CHANGED,
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_KERNEL,
- PROP_LATENCY
-};
-
-static guint gst_audio_fir_filter_signals[LAST_SIGNAL] = { 0, };
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_fir_filter_debug, "audiofirfilter", 0, \
- "Generic audio FIR filter plugin");
-
-GST_BOILERPLATE_FULL (GstAudioFIRFilter, gst_audio_fir_filter, GstAudioFilter,
- GST_TYPE_AUDIO_FX_BASE_FIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_fir_filter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_fir_filter_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_audio_fir_filter_finalize (GObject * object);
-
-static gboolean gst_audio_fir_filter_setup (GstAudioFilter * base,
- GstRingBufferSpec * format);
-
-/* Element class */
-static void
-gst_audio_fir_filter_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "Audio FIR filter", "Filter/Effect/Audio",
- "Generic audio FIR filter with custom filter kernel",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_fir_filter_class_init (GstAudioFIRFilterClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_fir_filter_set_property;
- gobject_class->get_property = gst_audio_fir_filter_get_property;
- gobject_class->finalize = gst_audio_fir_filter_finalize;
-
- g_object_class_install_property (gobject_class, PROP_KERNEL,
- g_param_spec_value_array ("kernel", "Filter Kernel",
- "Filter kernel for the FIR filter",
- g_param_spec_double ("Element", "Filter Kernel Element",
- "Element of the filter kernel", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_LATENCY,
- g_param_spec_uint64 ("latency", "Latecy",
- "Filter latency in samples",
- 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fir_filter_setup);
-
- /**
- * GstAudioFIRFilter::rate-changed:
- * @filter: the filter on which the signal is emitted
- * @rate: the new sampling rate
- *
- * Will be emitted when the sampling rate changes. The callbacks
- * will be called from the streaming thread and processing will
- * stop until the event is handled.
- */
- gst_audio_fir_filter_signals[SIGNAL_RATE_CHANGED] =
- g_signal_new ("rate-changed", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstAudioFIRFilterClass, rate_changed),
- NULL, NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-}
-
-static void
-gst_audio_fir_filter_update_kernel (GstAudioFIRFilter * self, GValueArray * va)
-{
- gdouble *kernel;
- guint i;
-
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
-
- if (va) {
- if (self->kernel)
- g_value_array_free (self->kernel);
-
- self->kernel = va;
- }
-
- kernel = g_new (gdouble, self->kernel->n_values);
-
- for (i = 0; i < self->kernel->n_values; i++) {
- GValue *v = g_value_array_get_nth (self->kernel, i);
- kernel[i] = g_value_get_double (v);
- }
-
- gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self),
- kernel, self->kernel->n_values, self->latency);
-}
-
-static void
-gst_audio_fir_filter_init (GstAudioFIRFilter * self,
- GstAudioFIRFilterClass * g_class)
-{
- GValue v = { 0, };
- GValueArray *va;
-
- self->latency = 0;
- va = g_value_array_new (1);
-
- g_value_init (&v, G_TYPE_DOUBLE);
- g_value_set_double (&v, 1.0);
- g_value_array_append (va, &v);
- g_value_unset (&v);
- gst_audio_fir_filter_update_kernel (self, va);
-
- self->lock = g_mutex_new ();
-}
-
-/* GstAudioFilter vmethod implementations */
-
-/* get notified of caps and plug in the correct process function */
-static gboolean
-gst_audio_fir_filter_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioFIRFilter *self = GST_AUDIO_FIR_FILTER (base);
-
- if (self->rate != format->rate) {
- g_signal_emit (G_OBJECT (self),
- gst_audio_fir_filter_signals[SIGNAL_RATE_CHANGED], 0, format->rate);
- self->rate = format->rate;
- }
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
-
-static void
-gst_audio_fir_filter_finalize (GObject * object)
-{
- GstAudioFIRFilter *self = GST_AUDIO_FIR_FILTER (object);
-
- g_mutex_free (self->lock);
- self->lock = NULL;
-
- if (self->kernel)
- g_value_array_free (self->kernel);
- self->kernel = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_fir_filter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioFIRFilter *self = GST_AUDIO_FIR_FILTER (object);
-
- g_return_if_fail (GST_IS_AUDIO_FIR_FILTER (self));
-
- switch (prop_id) {
- case PROP_KERNEL:
- g_mutex_lock (self->lock);
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
-
- gst_audio_fir_filter_update_kernel (self, g_value_dup_boxed (value));
- g_mutex_unlock (self->lock);
- break;
- case PROP_LATENCY:
- g_mutex_lock (self->lock);
- self->latency = g_value_get_uint64 (value);
- gst_audio_fir_filter_update_kernel (self, NULL);
- g_mutex_unlock (self->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_fir_filter_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioFIRFilter *self = GST_AUDIO_FIR_FILTER (object);
-
- switch (prop_id) {
- case PROP_KERNEL:
- g_value_set_boxed (value, self->kernel);
- break;
- case PROP_LATENCY:
- g_value_set_uint64 (value, self->latency);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/audiofx/audiofirfilter.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef __GST_AUDIO_FIR_FILTER_H__
-#define __GST_AUDIO_FIR_FILTER_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/audio/gstaudiofilter.h>
-
-#include "audiofxbasefirfilter.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_FIR_FILTER \
- (gst_audio_fir_filter_get_type())
-#define GST_AUDIO_FIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_FIR_FILTER,GstAudioFIRFilter))
-#define GST_AUDIO_FIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_FIR_FILTER,GstAudioFIRFilterClass))
-#define GST_IS_AUDIO_FIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_FIR_FILTER))
-#define GST_IS_AUDIO_FIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_FIR_FILTER))
-
-typedef struct _GstAudioFIRFilter GstAudioFIRFilter;
-typedef struct _GstAudioFIRFilterClass GstAudioFIRFilterClass;
-
-/**
- * GstAudioFIRFilter:
- *
- * Opaque data structure.
- */
-struct _GstAudioFIRFilter {
- GstAudioFXBaseFIRFilter parent;
-
- GValueArray *kernel;
- guint64 latency;
-
- /* < private > */
- GMutex *lock;
- gint rate;
-};
-
-struct _GstAudioFIRFilterClass {
- GstAudioFXBaseFIRFilterClass parent;
-
- void (*rate_changed) (GstElement * element, gint rate);
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_fir_filter_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_FIR_FILTER_H__ */
--- a/gst_plugins_good/gst/audiofx/audiofx.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiopanorama.h"
-#include "audioinvert.h"
-#include "audiokaraoke.h"
-#include "audioamplify.h"
-#include "audiodynamic.h"
-#include "audiocheblimit.h"
-#include "audiochebband.h"
-#include "audioiirfilter.h"
-#include "audiowsincband.h"
-#include "audiowsinclimit.h"
-#include "audiofirfilter.h"
-#include "audioecho.h"
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and pad templates
- * register the features
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- /* initialize gst controller library */
- gst_controller_init (NULL, NULL);
-
- return (gst_element_register (plugin, "audiopanorama", GST_RANK_NONE,
- GST_TYPE_AUDIO_PANORAMA) &&
- gst_element_register (plugin, "audioinvert", GST_RANK_NONE,
- GST_TYPE_AUDIO_INVERT) &&
- gst_element_register (plugin, "audiokaraoke", GST_RANK_NONE,
- GST_TYPE_AUDIO_KARAOKE) &&
- gst_element_register (plugin, "audioamplify", GST_RANK_NONE,
- GST_TYPE_AUDIO_AMPLIFY) &&
- gst_element_register (plugin, "audiodynamic", GST_RANK_NONE,
- GST_TYPE_AUDIO_DYNAMIC) &&
- gst_element_register (plugin, "audiocheblimit", GST_RANK_NONE,
- GST_TYPE_AUDIO_CHEB_LIMIT) &&
- gst_element_register (plugin, "audiochebband", GST_RANK_NONE,
- GST_TYPE_AUDIO_CHEB_BAND) &&
- gst_element_register (plugin, "audioiirfilter", GST_RANK_NONE,
- GST_TYPE_AUDIO_IIR_FILTER) &&
- gst_element_register (plugin, "audiowsinclimit", GST_RANK_NONE,
- GST_TYPE_AUDIO_WSINC_LIMIT) &&
- gst_element_register (plugin, "audiowsincband", GST_RANK_NONE,
- GST_TYPE_AUDIO_WSINC_BAND) &&
- gst_element_register (plugin, "audiofirfilter", GST_RANK_NONE,
- GST_TYPE_AUDIO_FIR_FILTER) &&
- gst_element_register (plugin, "audioecho", GST_RANK_NONE,
- GST_TYPE_AUDIO_ECHO));
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "audiofx",
- "Audio effects plugin",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
--- a/gst_plugins_good/gst/audiofx/audiofxbasefirfilter.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,527 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- *
- * TODO: - Implement the convolution in place, probably only makes sense
- * when using FFT convolution as currently the convolution itself
- * is probably the bottleneck
- * - Maybe allow cascading the filter to get a better stopband attenuation.
- * Can be done by convolving a filter kernel with itself
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiofxbasefirfilter.h"
-
-#define GST_CAT_DEFAULT gst_audio_fx_base_fir_filter_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-#define ALLOWED_CAPS \
- "audio/x-raw-float, " \
- " width = (int) { 32, 64 }, " \
- " endianness = (int) BYTE_ORDER, " \
- " rate = (int) [ 1, MAX ], " \
- " channels = (int) [ 1, MAX ]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_fir_filter_debug, "audiofxbasefirfilter", 0, \
- "FIR filter base class");
-
-GST_BOILERPLATE_FULL (GstAudioFXBaseFIRFilter, gst_audio_fx_base_fir_filter,
- GstAudioFilter, GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static GstFlowReturn gst_audio_fx_base_fir_filter_transform (GstBaseTransform *
- base, GstBuffer * inbuf, GstBuffer * outbuf);
-static gboolean gst_audio_fx_base_fir_filter_start (GstBaseTransform * base);
-static gboolean gst_audio_fx_base_fir_filter_stop (GstBaseTransform * base);
-static gboolean gst_audio_fx_base_fir_filter_event (GstBaseTransform * base,
- GstEvent * event);
-static gboolean gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
- GstRingBufferSpec * format);
-
-static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad,
- GstQuery * query);
-static const GstQueryType *gst_audio_fx_base_fir_filter_query_type (GstPad *
- pad);
-
-/* Element class */
-
-static void
-gst_audio_fx_base_fir_filter_dispose (GObject * object)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (object);
-
- if (self->residue) {
- g_free (self->residue);
- self->residue = NULL;
- }
-
- if (self->kernel) {
- g_free (self->kernel);
- self->kernel = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_audio_fx_base_fir_filter_base_init (gpointer g_class)
-{
- GstCaps *caps;
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (g_class),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->dispose = gst_audio_fx_base_fir_filter_dispose;
-
- trans_class->transform =
- GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform);
- trans_class->start = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_start);
- trans_class->stop = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_stop);
- trans_class->event = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_event);
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_setup);
-}
-
-static void
-gst_audio_fx_base_fir_filter_init (GstAudioFXBaseFIRFilter * self,
- GstAudioFXBaseFIRFilterClass * g_class)
-{
- self->kernel = NULL;
- self->residue = NULL;
-
- self->next_ts = GST_CLOCK_TIME_NONE;
- self->next_off = GST_BUFFER_OFFSET_NONE;
-
- gst_pad_set_query_function (GST_BASE_TRANSFORM (self)->srcpad,
- gst_audio_fx_base_fir_filter_query);
- gst_pad_set_query_type_function (GST_BASE_TRANSFORM (self)->srcpad,
- gst_audio_fx_base_fir_filter_query_type);
-}
-
-#define DEFINE_PROCESS_FUNC(width,ctype) \
-static void \
-process_##width (GstAudioFXBaseFIRFilter * self, g##ctype * src, g##ctype * dst, guint input_samples) \
-{ \
- gint kernel_length = self->kernel_length; \
- gint i, j, k, l; \
- gint channels = GST_AUDIO_FILTER (self)->format.channels; \
- gint res_start; \
- \
- /* convolution */ \
- for (i = 0; i < input_samples; i++) { \
- dst[i] = 0.0; \
- k = i % channels; \
- l = i / channels; \
- for (j = 0; j < kernel_length; j++) \
- if (l < j) \
- dst[i] += \
- self->residue[(kernel_length + l - j) * channels + \
- k] * self->kernel[j]; \
- else \
- dst[i] += src[(l - j) * channels + k] * self->kernel[j]; \
- } \
- \
- /* copy the tail of the current input buffer to the residue, while \
- * keeping parts of the residue if the input buffer is smaller than \
- * the kernel length */ \
- if (input_samples < kernel_length * channels) \
- res_start = kernel_length * channels - input_samples; \
- else \
- res_start = 0; \
- \
- for (i = 0; i < res_start; i++) \
- self->residue[i] = self->residue[i + input_samples]; \
- for (i = res_start; i < kernel_length * channels; i++) \
- self->residue[i] = src[input_samples - kernel_length * channels + i]; \
- \
- self->residue_length += kernel_length * channels - res_start; \
- if (self->residue_length > kernel_length * channels) \
- self->residue_length = kernel_length * channels; \
-}
-
-DEFINE_PROCESS_FUNC (32, float);
-DEFINE_PROCESS_FUNC (64, double);
-
-#undef DEFINE_PROCESS_FUNC
-
-void
-gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
-{
- GstBuffer *outbuf;
- GstFlowReturn res;
- gint rate = GST_AUDIO_FILTER (self)->format.rate;
- gint channels = GST_AUDIO_FILTER (self)->format.channels;
- gint outsize, outsamples;
- gint diffsize, diffsamples;
- guint8 *in, *out;
-
- if (channels == 0 || rate == 0) {
- self->residue_length = 0;
- return;
- }
-
- /* Calculate the number of samples and their memory size that
- * should be pushed from the residue */
- outsamples = MIN (self->latency, self->residue_length / channels);
- outsize = outsamples * channels * (GST_AUDIO_FILTER (self)->format.width / 8);
- if (outsize == 0) {
- self->residue_length = 0;
- return;
- }
-
- /* Process the difference between latency and residue_length samples
- * to start at the actual data instead of starting at the zeros before
- * when we only got one buffer smaller than latency */
- diffsamples = self->latency - self->residue_length / channels;
- diffsize =
- diffsamples * channels * (GST_AUDIO_FILTER (self)->format.width / 8);
- if (diffsize > 0) {
- in = g_new0 (guint8, diffsize);
- out = g_new0 (guint8, diffsize);
- self->process (self, in, out, diffsamples * channels);
- g_free (in);
- g_free (out);
- }
-
- res = gst_pad_alloc_buffer (GST_BASE_TRANSFORM (self)->srcpad,
- GST_BUFFER_OFFSET_NONE, outsize,
- GST_PAD_CAPS (GST_BASE_TRANSFORM (self)->srcpad), &outbuf);
-
- if (G_UNLIKELY (res != GST_FLOW_OK)) {
- GST_WARNING_OBJECT (self, "failed allocating buffer of %d bytes", outsize);
- self->residue_length = 0;
- return;
- }
-
- /* Convolve the residue with zeros to get the actual remaining data */
- in = g_new0 (guint8, outsize);
- self->process (self, in, GST_BUFFER_DATA (outbuf), outsamples * channels);
- g_free (in);
-
- /* Set timestamp, offset, etc from the values we
- * saved when processing the regular buffers */
- if (GST_CLOCK_TIME_IS_VALID (self->next_ts))
- GST_BUFFER_TIMESTAMP (outbuf) = self->next_ts;
- else
- GST_BUFFER_TIMESTAMP (outbuf) = 0;
- GST_BUFFER_DURATION (outbuf) =
- gst_util_uint64_scale (outsamples, GST_SECOND, rate);
- self->next_ts += gst_util_uint64_scale (outsamples, GST_SECOND, rate);
-
- if (self->next_off != GST_BUFFER_OFFSET_NONE) {
- GST_BUFFER_OFFSET (outbuf) = self->next_off;
- GST_BUFFER_OFFSET_END (outbuf) = self->next_off + outsamples;
- self->next_off = GST_BUFFER_OFFSET_END (outbuf);
- }
-
- GST_DEBUG_OBJECT (self, "Pushing residue buffer of size %d with timestamp: %"
- GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %lld,"
- " offset_end: %lld, nsamples: %d", GST_BUFFER_SIZE (outbuf),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
- GST_BUFFER_OFFSET_END (outbuf), outsamples);
-
- res = gst_pad_push (GST_BASE_TRANSFORM (self)->srcpad, outbuf);
-
- if (G_UNLIKELY (res != GST_FLOW_OK)) {
- GST_WARNING_OBJECT (self, "failed to push residue");
- }
-
- self->residue_length = 0;
-}
-
-/* GstAudioFilter vmethod implementations */
-
-/* get notified of caps and plug in the correct process function */
-static gboolean
-gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
- GstRingBufferSpec * format)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
- gboolean ret = TRUE;
-
- if (self->residue) {
- gst_audio_fx_base_fir_filter_push_residue (self);
- g_free (self->residue);
- self->residue = NULL;
- self->residue_length = 0;
- self->next_ts = GST_CLOCK_TIME_NONE;
- self->next_off = GST_BUFFER_OFFSET_NONE;
- }
-
- if (format->width == 32)
- self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_32;
- else if (format->width == 64)
- self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_64;
- else
- ret = FALSE;
-
- return TRUE;
-}
-
-/* GstBaseTransform vmethod implementations */
-
-static GstFlowReturn
-gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base,
- GstBuffer * inbuf, GstBuffer * outbuf)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
- GstClockTime timestamp;
- gint channels = GST_AUDIO_FILTER (self)->format.channels;
- gint rate = GST_AUDIO_FILTER (self)->format.rate;
- gint input_samples =
- GST_BUFFER_SIZE (outbuf) / (GST_AUDIO_FILTER (self)->format.width / 8);
- gint output_samples = input_samples;
- gint diff = 0;
-
- timestamp = GST_BUFFER_TIMESTAMP (outbuf);
- if (!GST_CLOCK_TIME_IS_VALID (timestamp)) {
- GST_ERROR_OBJECT (self, "Invalid timestamp");
- return GST_FLOW_ERROR;
- }
-
- gst_object_sync_values (G_OBJECT (self), timestamp);
-
- g_return_val_if_fail (self->kernel != NULL, GST_FLOW_ERROR);
- g_return_val_if_fail (channels != 0, GST_FLOW_ERROR);
-
- if (!self->residue)
- self->residue = g_new0 (gdouble, self->kernel_length * channels);
-
- /* Reset the residue if already existing on discont buffers */
- if (GST_BUFFER_IS_DISCONT (inbuf) || (GST_CLOCK_TIME_IS_VALID (self->next_ts)
- && timestamp - gst_util_uint64_scale (MIN (self->latency,
- self->residue_length / channels), GST_SECOND,
- rate) - self->next_ts > 5 * GST_MSECOND)) {
- GST_DEBUG_OBJECT (self, "Discontinuity detected - flushing");
- if (GST_CLOCK_TIME_IS_VALID (self->next_ts))
- gst_audio_fx_base_fir_filter_push_residue (self);
- self->residue_length = 0;
- self->next_ts = timestamp;
- self->next_off = GST_BUFFER_OFFSET (inbuf);
- } else if (!GST_CLOCK_TIME_IS_VALID (self->next_ts)) {
- self->next_ts = timestamp;
- self->next_off = GST_BUFFER_OFFSET (inbuf);
- }
-
- /* Calculate the number of samples we can push out now without outputting
- * latency zeros in the beginning */
- diff = self->latency * channels - self->residue_length;
- if (diff > 0)
- output_samples -= diff;
-
- self->process (self, GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (outbuf),
- input_samples);
-
- if (output_samples <= 0) {
- return GST_BASE_TRANSFORM_FLOW_DROPPED;
- }
-
- GST_BUFFER_TIMESTAMP (outbuf) = self->next_ts;
- GST_BUFFER_DURATION (outbuf) =
- gst_util_uint64_scale (output_samples / channels, GST_SECOND, rate);
- GST_BUFFER_OFFSET (outbuf) = self->next_off;
- if (GST_BUFFER_OFFSET_IS_VALID (outbuf))
- GST_BUFFER_OFFSET_END (outbuf) = self->next_off + output_samples / channels;
- else
- GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
-
- if (output_samples < input_samples) {
- GST_BUFFER_DATA (outbuf) +=
- diff * (GST_AUDIO_FILTER (self)->format.width / 8);
- GST_BUFFER_SIZE (outbuf) -=
- diff * (GST_AUDIO_FILTER (self)->format.width / 8);
- }
-
- self->next_ts += GST_BUFFER_DURATION (outbuf);
- self->next_off = GST_BUFFER_OFFSET_END (outbuf);
-
- GST_DEBUG_OBJECT (self, "Pushing buffer of size %d with timestamp: %"
- GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %lld,"
- " offset_end: %lld, nsamples: %d", GST_BUFFER_SIZE (outbuf),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
- GST_BUFFER_OFFSET_END (outbuf), output_samples / channels);
-
- return GST_FLOW_OK;
-}
-
-static gboolean
-gst_audio_fx_base_fir_filter_start (GstBaseTransform * base)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
-
- self->residue_length = 0;
- self->next_ts = GST_CLOCK_TIME_NONE;
- self->next_off = GST_BUFFER_OFFSET_NONE;
-
- return TRUE;
-}
-
-static gboolean
-gst_audio_fx_base_fir_filter_stop (GstBaseTransform * base)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
-
- g_free (self->residue);
- self->residue = NULL;
-
- return TRUE;
-}
-
-static gboolean
-gst_audio_fx_base_fir_filter_query (GstPad * pad, GstQuery * query)
-{
- GstAudioFXBaseFIRFilter *self =
- GST_AUDIO_FX_BASE_FIR_FILTER (gst_pad_get_parent (pad));
- gboolean res = TRUE;
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_LATENCY:
- {
- GstClockTime min, max;
- gboolean live;
- guint64 latency;
- GstPad *peer;
- gint rate = GST_AUDIO_FILTER (self)->format.rate;
-
- if (rate == 0) {
- res = FALSE;
- } else if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM (self)->sinkpad))) {
- if ((res = gst_pad_query (peer, query))) {
- gst_query_parse_latency (query, &live, &min, &max);
-
- GST_DEBUG_OBJECT (self, "Peer latency: min %"
- GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
- GST_TIME_ARGS (min), GST_TIME_ARGS (max));
-
- /* add our own latency */
- latency = gst_util_uint64_scale (self->latency, GST_SECOND, rate);
-
- GST_DEBUG_OBJECT (self, "Our latency: %"
- GST_TIME_FORMAT, GST_TIME_ARGS (latency));
-
- min += latency;
- if (max != GST_CLOCK_TIME_NONE)
- max += latency;
-
- GST_DEBUG_OBJECT (self, "Calculated total latency : min %"
- GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
- GST_TIME_ARGS (min), GST_TIME_ARGS (max));
-
- gst_query_set_latency (query, live, min, max);
- }
- gst_object_unref (peer);
- }
- break;
- }
- default:
- res = gst_pad_query_default (pad, query);
- break;
- }
- gst_object_unref (self);
- return res;
-}
-
-static const GstQueryType *
-gst_audio_fx_base_fir_filter_query_type (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_LATENCY,
- 0
- };
-
- return types;
-}
-
-static gboolean
-gst_audio_fx_base_fir_filter_event (GstBaseTransform * base, GstEvent * event)
-{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- gst_audio_fx_base_fir_filter_push_residue (self);
- self->next_ts = GST_CLOCK_TIME_NONE;
- self->next_off = GST_BUFFER_OFFSET_NONE;
- break;
- default:
- break;
- }
-
- return GST_BASE_TRANSFORM_CLASS (parent_class)->event (base, event);
-}
-
-void
-gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
- gdouble * kernel, guint kernel_length, guint64 latency)
-{
- g_return_if_fail (kernel != NULL);
- g_return_if_fail (self != NULL);
-
- GST_BASE_TRANSFORM_LOCK (self);
- if (self->residue) {
- gst_audio_fx_base_fir_filter_push_residue (self);
- self->next_ts = GST_CLOCK_TIME_NONE;
- self->next_off = GST_BUFFER_OFFSET_NONE;
- self->residue_length = 0;
- }
-
- g_free (self->kernel);
- g_free (self->residue);
-
- self->kernel = kernel;
- self->kernel_length = kernel_length;
-
- if (GST_AUDIO_FILTER (self)->format.channels) {
- self->residue =
- g_new0 (gdouble,
- kernel_length * GST_AUDIO_FILTER (self)->format.channels);
- self->residue_length = 0;
- }
-
- if (self->latency != latency) {
- self->latency = latency;
- gst_element_post_message (GST_ELEMENT (self),
- gst_message_new_latency (GST_OBJECT (self)));
- }
-
- GST_BASE_TRANSFORM_UNLOCK (self);
-}
--- a/gst_plugins_good/gst/audiofx/audiofxbasefirfilter.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef __GST_AUDIO_FX_BASE_FIR_FILTER_H__
-#define __GST_AUDIO_FX_BASE_FIR_FILTER_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_FX_BASE_FIR_FILTER \
- (gst_audio_fx_base_fir_filter_get_type())
-#define GST_AUDIO_FX_BASE_FIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_FX_BASE_FIR_FILTER,GstAudioFXBaseFIRFilter))
-#define GST_AUDIO_FX_BASE_FIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_FX_BASE_FIR_FILTER,GstAudioFXBaseFIRFilterClass))
-#define GST_IS_AUDIO_FX_BASE_FIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_FX_BASE_FIR_FILTER))
-#define GST_IS_AUDIO_FX_BASE_FIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_FX_BASE_FIR_FILTER))
-
-typedef struct _GstAudioFXBaseFIRFilter GstAudioFXBaseFIRFilter;
-typedef struct _GstAudioFXBaseFIRFilterClass GstAudioFXBaseFIRFilterClass;
-
-typedef void (*GstAudioFXBaseFIRFilterProcessFunc) (GstAudioFXBaseFIRFilter *, guint8 *, guint8 *, guint);
-
-/**
- * GstAudioFXBaseFIRFilter:
- *
- * Opaque data structure.
- */
-struct _GstAudioFXBaseFIRFilter {
- GstAudioFilter element;
-
- /* < private > */
- GstAudioFXBaseFIRFilterProcessFunc process;
-
- gdouble *kernel; /* filter kernel */
- guint kernel_length; /* length of the filter kernel */
- gdouble *residue; /* buffer for left-over samples from previous buffer */
- guint residue_length;
-
- guint64 latency;
-
- GstClockTime next_ts;
- guint64 next_off;
-};
-
-struct _GstAudioFXBaseFIRFilterClass {
- GstAudioFilterClass parent_class;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_fx_base_fir_filter_get_type (void);
-void gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter *filter, gdouble *kernel, guint kernel_length, guint64 latency);
-void gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter *filter);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_FX_BASE_FIR_FILTER_H__ */
--- a/gst_plugins_good/gst/audiofx/audiofxbaseiirfilter.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include <math.h>
-
-#include "audiofxbaseiirfilter.h"
-
-#define GST_CAT_DEFAULT gst_audio_fx_base_iir_filter_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-#define ALLOWED_CAPS \
- "audio/x-raw-float," \
- " width = (int) { 32, 64 }, " \
- " endianness = (int) BYTE_ORDER," \
- " rate = (int) [ 1, MAX ]," \
- " channels = (int) [ 1, MAX ]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_iir_filter_debug, "audiofxbaseiirfilter", 0, "Audio IIR Filter Base Class");
-
-GST_BOILERPLATE_FULL (GstAudioFXBaseIIRFilter,
- gst_audio_fx_base_iir_filter, GstAudioFilter, GST_TYPE_AUDIO_FILTER,
- DEBUG_INIT);
-
-static gboolean gst_audio_fx_base_iir_filter_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-static GstFlowReturn
-gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-static gboolean gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base);
-
-static void process_64 (GstAudioFXBaseIIRFilter * filter,
- gdouble * data, guint num_samples);
-static void process_32 (GstAudioFXBaseIIRFilter * filter,
- gfloat * data, guint num_samples);
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_fx_base_iir_filter_base_init (gpointer klass)
-{
- GstCaps *caps;
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_fx_base_iir_filter_dispose (GObject * object)
-{
- GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (object);
-
- if (filter->a) {
- g_free (filter->a);
- filter->a = NULL;
- }
-
- if (filter->b) {
- g_free (filter->b);
- filter->b = NULL;
- }
-
- if (filter->channels) {
- GstAudioFXBaseIIRFilterChannelCtx *ctx;
- guint i;
-
- for (i = 0; i < filter->nchannels; i++) {
- ctx = &filter->channels[i];
- g_free (ctx->x);
- g_free (ctx->y);
- }
-
- g_free (filter->channels);
- filter->channels = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_audio_fx_base_iir_filter_class_init (GstAudioFXBaseIIRFilterClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->dispose = gst_audio_fx_base_iir_filter_dispose;
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_setup);
-
- trans_class->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_transform_ip);
- trans_class->stop = GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_stop);
-}
-
-static void
-gst_audio_fx_base_iir_filter_init (GstAudioFXBaseIIRFilter * filter,
- GstAudioFXBaseIIRFilterClass * klass)
-{
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
-
- filter->a = NULL;
- filter->na = 0;
- filter->b = NULL;
- filter->nb = 0;
- filter->channels = NULL;
- filter->nchannels = 0;
-}
-
-/* Evaluate the transfer function that corresponds to the IIR
- * coefficients at zr + zi*I and return the magnitude */
-gdouble
-gst_audio_fx_base_iir_filter_calculate_gain (gdouble * a, guint na, gdouble * b,
- guint nb, gdouble zr, gdouble zi)
-{
- gdouble sum_ar, sum_ai;
- gdouble sum_br, sum_bi;
- gdouble gain_r, gain_i;
-
- gdouble sum_r_old;
- gdouble sum_i_old;
-
- gint i;
-
- sum_ar = 0.0;
- sum_ai = 0.0;
- for (i = na - 1; i >= 0; i--) {
- sum_r_old = sum_ar;
- sum_i_old = sum_ai;
-
- sum_ar = (sum_r_old * zr - sum_i_old * zi) + a[i];
- sum_ai = (sum_r_old * zi + sum_i_old * zr) + 0.0;
- }
-
- sum_br = 0.0;
- sum_bi = 0.0;
- for (i = nb - 1; i >= 0; i--) {
- sum_r_old = sum_br;
- sum_i_old = sum_bi;
-
- sum_br = (sum_r_old * zr - sum_i_old * zi) - b[i];
- sum_bi = (sum_r_old * zi + sum_i_old * zr) - 0.0;
- }
- sum_br += 1.0;
- sum_bi += 0.0;
-
- gain_r =
- (sum_ar * sum_br + sum_ai * sum_bi) / (sum_br * sum_br + sum_bi * sum_bi);
- gain_i =
- (sum_ai * sum_br - sum_ar * sum_bi) / (sum_br * sum_br + sum_bi * sum_bi);
-
- return (sqrt (gain_r * gain_r + gain_i * gain_i));
-}
-
-void
-gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter * filter,
- gdouble * a, guint na, gdouble * b, guint nb)
-{
- guint i;
-
- g_return_if_fail (GST_IS_AUDIO_FX_BASE_IIR_FILTER (filter));
-
- GST_BASE_TRANSFORM_LOCK (filter);
-
- g_free (filter->a);
- g_free (filter->b);
-
- filter->a = filter->b = NULL;
-
- if (filter->channels) {
- GstAudioFXBaseIIRFilterChannelCtx *ctx;
- gboolean free = (na != filter->na || nb != filter->nb);
-
- for (i = 0; i < filter->nchannels; i++) {
- ctx = &filter->channels[i];
-
- if (free)
- g_free (ctx->x);
- else
- memset (ctx->x, 0, filter->na * sizeof (gdouble));
-
- if (free)
- g_free (ctx->y);
- else
- memset (ctx->y, 0, filter->nb * sizeof (gdouble));
- }
-
- g_free (filter->channels);
- filter->channels = NULL;
- }
-
- filter->na = na;
- filter->nb = nb;
-
- filter->a = a;
- filter->b = b;
-
- if (filter->nchannels && !filter->channels) {
- GstAudioFXBaseIIRFilterChannelCtx *ctx;
-
- filter->channels =
- g_new0 (GstAudioFXBaseIIRFilterChannelCtx, filter->nchannels);
- for (i = 0; i < filter->nchannels; i++) {
- ctx = &filter->channels[i];
-
- ctx->x = g_new0 (gdouble, filter->na);
- ctx->y = g_new0 (gdouble, filter->nb);
- }
- }
-
- GST_BASE_TRANSFORM_UNLOCK (filter);
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base,
- GstRingBufferSpec * format)
-{
- GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
- gboolean ret = TRUE;
-
- if (format->width == 32)
- filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
- process_32;
- else if (format->width == 64)
- filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
- process_64;
- else
- ret = FALSE;
-
- if (format->channels != filter->nchannels) {
- guint i;
- GstAudioFXBaseIIRFilterChannelCtx *ctx;
-
- if (filter->channels) {
-
- for (i = 0; i < filter->nchannels; i++) {
- ctx = &filter->channels[i];
-
- g_free (ctx->x);
- g_free (ctx->y);
- }
-
- g_free (filter->channels);
- filter->channels = NULL;
- }
-
- filter->nchannels = format->channels;
-
- filter->channels =
- g_new0 (GstAudioFXBaseIIRFilterChannelCtx, filter->nchannels);
- for (i = 0; i < filter->nchannels; i++) {
- ctx = &filter->channels[i];
-
- ctx->x = g_new0 (gdouble, filter->na);
- ctx->y = g_new0 (gdouble, filter->nb);
- }
- }
-
- return ret;
-}
-
-static inline gdouble
-process (GstAudioFXBaseIIRFilter * filter,
- GstAudioFXBaseIIRFilterChannelCtx * ctx, gdouble x0)
-{
- gdouble val = filter->a[0] * x0;
- gint i, j;
-
- for (i = 1, j = ctx->x_pos; i < filter->na; i++) {
- val += filter->a[i] * ctx->x[j];
- j--;
- if (j < 0)
- j = filter->na - 1;
- }
-
- for (i = 1, j = ctx->y_pos; i < filter->nb; i++) {
- val += filter->b[i] * ctx->y[j];
- j--;
- if (j < 0)
- j = filter->nb - 1;
- }
-
- if (ctx->x) {
- ctx->x_pos++;
- if (ctx->x_pos >= filter->na)
- ctx->x_pos = 0;
- ctx->x[ctx->x_pos] = x0;
- }
- if (ctx->y) {
- ctx->y_pos++;
- if (ctx->y_pos >= filter->nb)
- ctx->y_pos = 0;
-
- ctx->y[ctx->y_pos] = val;
- }
-
- return val;
-}
-
-#define DEFINE_PROCESS_FUNC(width,ctype) \
-static void \
-process_##width (GstAudioFXBaseIIRFilter * filter, \
- g##ctype * data, guint num_samples) \
-{ \
- gint i, j, channels = GST_AUDIO_FILTER (filter)->format.channels; \
- gdouble val; \
- \
- for (i = 0; i < num_samples / channels; i++) { \
- for (j = 0; j < channels; j++) { \
- val = process (filter, &filter->channels[j], *data); \
- *data++ = val; \
- } \
- } \
-}
-
-DEFINE_PROCESS_FUNC (32, float);
-DEFINE_PROCESS_FUNC (64, double);
-
-#undef DEFINE_PROCESS_FUNC
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
- GstBuffer * buf)
-{
- GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
- if (gst_base_transform_is_passthrough (base))
- return GST_FLOW_OK;
-
- g_return_val_if_fail (filter->a != NULL, GST_FLOW_ERROR);
-
- filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
-
-
-static gboolean
-gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base)
-{
- GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
- guint channels = GST_AUDIO_FILTER (filter)->format.channels;
- GstAudioFXBaseIIRFilterChannelCtx *ctx;
- guint i;
-
- /* Reset the history of input and output values if
- * already existing */
- if (channels && filter->channels) {
- for (i = 0; i < channels; i++) {
- ctx = &filter->channels[i];
- g_free (ctx->x);
- g_free (ctx->y);
- }
- g_free (filter->channels);
- }
- filter->channels = NULL;
-
- return TRUE;
-}
--- a/gst_plugins_good/gst/audiofx/audiofxbaseiirfilter.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_FX_BASE_IIR_FILTER_H__
-#define __GST_AUDIO_FX_BASE_IIR_FILTER_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_FX_BASE_IIR_FILTER (gst_audio_fx_base_iir_filter_get_type())
-#define GST_AUDIO_FX_BASE_IIR_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_FX_BASE_IIR_FILTER,GstAudioFXBaseIIRFilter))
-#define GST_IS_AUDIO_FX_BASE_IIR_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_FX_BASE_IIR_FILTER))
-#define GST_AUDIO_FX_BASE_IIR_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_FX_BASE_IIR_FILTER,GstAudioFXBaseIIRFilterClass))
-#define GST_IS_AUDIO_FX_BASE_IIR_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_FX_BASE_IIR_FILTER))
-#define GST_AUDIO_FX_BASE_IIR_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_FX_BASE_IIR_FILTER,GstAudioFXBaseIIRFilterClass))
-typedef struct _GstAudioFXBaseIIRFilter GstAudioFXBaseIIRFilter;
-typedef struct _GstAudioFXBaseIIRFilterClass GstAudioFXBaseIIRFilterClass;
-
-typedef void (*GstAudioFXBaseIIRFilterProcessFunc) (GstAudioFXBaseIIRFilter *, guint8 *, guint);
-
-typedef struct
-{
- gdouble *x;
- gint x_pos;
- gdouble *y;
- gint y_pos;
-} GstAudioFXBaseIIRFilterChannelCtx;
-
-struct _GstAudioFXBaseIIRFilter
-{
- GstAudioFilter audiofilter;
-
- /* < private > */
- GstAudioFXBaseIIRFilterProcessFunc process;
-
- gboolean have_coeffs;
- gdouble *a;
- guint na;
- gdouble *b;
- guint nb;
- GstAudioFXBaseIIRFilterChannelCtx *channels;
- guint nchannels;
-};
-
-struct _GstAudioFXBaseIIRFilterClass
-{
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_fx_base_iir_filter_get_type (void);
-void gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter *filter, gdouble *a, guint na, gdouble *b, guint nb);
-gdouble gst_audio_fx_base_iir_filter_calculate_gain (gdouble *a, guint na, gdouble *b, guint nb, gdouble zr, gdouble zi);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_FX_BASE_IIR_FILTER_H__ */
--- a/gst_plugins_good/gst/audiofx/audioiirfilter.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-/**
- * SECTION:element-audioiirfilter
- *
- * audioiirfilter implements a generic audio <ulink url="http://en.wikipedia.org/wiki/Infinite_impulse_response">IIR filter</ulink>. Before usage the
- * "a" and "b" properties have to be set to the filter coefficients that
- * should be used.
- *
- * The filter coefficients describe the numerator and denominator of the
- * transfer function.
- *
- * To change the filter coefficients whenever the sampling rate changes the
- * "rate-changed" signal can be used. This should be done for most
- * IIR filters as they're depending on the sampling rate.
- *
- * <refsect2>
- * <title>Example application</title>
- * |[
- * <xi:include xmlns:xi="http://www.w3.org/2003/XInclude" parse="text" href="../../../../tests/examples/audiofx/iirfilter-example.c" />
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audioiirfilter.h"
-
-#define GST_CAT_DEFAULT gst_audio_iir_filter_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- SIGNAL_RATE_CHANGED,
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_A,
- PROP_B
-};
-
-static guint gst_audio_iir_filter_signals[LAST_SIGNAL] = { 0, };
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_iir_filter_debug, "audioiirfilter", 0, \
- "Generic audio IIR filter plugin");
-
-GST_BOILERPLATE_FULL (GstAudioIIRFilter, gst_audio_iir_filter, GstAudioFilter,
- GST_TYPE_AUDIO_FX_BASE_IIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_iir_filter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_iir_filter_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_audio_iir_filter_finalize (GObject * object);
-
-static gboolean gst_audio_iir_filter_setup (GstAudioFilter * base,
- GstRingBufferSpec * format);
-
-/* Element class */
-static void
-gst_audio_iir_filter_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "Audio IIR filter", "Filter/Effect/Audio",
- "Generic audio IIR filter with custom filter kernel",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_iir_filter_class_init (GstAudioIIRFilterClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_iir_filter_set_property;
- gobject_class->get_property = gst_audio_iir_filter_get_property;
- gobject_class->finalize = gst_audio_iir_filter_finalize;
-
- g_object_class_install_property (gobject_class, PROP_A,
- g_param_spec_value_array ("a", "A",
- "Filter coefficients (numerator of transfer function)",
- g_param_spec_double ("Coefficient", "Filter Coefficient",
- "Filter coefficient", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_B,
- g_param_spec_value_array ("b", "B",
- "Filter coefficients (denominator of transfer function)",
- g_param_spec_double ("Coefficient", "Filter Coefficient",
- "Filter coefficient", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_iir_filter_setup);
-
- /**
- * GstAudioIIRFilter::rate-changed:
- * @filter: the filter on which the signal is emitted
- * @rate: the new sampling rate
- *
- * Will be emitted when the sampling rate changes. The callbacks
- * will be called from the streaming thread and processing will
- * stop until the event is handled.
- */
- gst_audio_iir_filter_signals[SIGNAL_RATE_CHANGED] =
- g_signal_new ("rate-changed", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstAudioIIRFilterClass, rate_changed),
- NULL, NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-}
-
-static void
-gst_audio_iir_filter_update_coefficients (GstAudioIIRFilter * self,
- GValueArray * va, GValueArray * vb)
-{
- gdouble *a = NULL, *b = NULL;
- guint i;
-
- if (va) {
- if (self->a)
- g_value_array_free (self->a);
-
- self->a = va;
- }
- if (vb) {
- if (self->b)
- g_value_array_free (self->b);
-
- self->b = vb;
- }
-
- if (self->a && self->a->n_values > 0)
- a = g_new (gdouble, self->a->n_values);
- if (self->b && self->b->n_values > 0)
- b = g_new (gdouble, self->b->n_values);
-
- if (self->a) {
- for (i = 0; i < self->a->n_values; i++) {
- GValue *v = g_value_array_get_nth (self->a, i);
- a[i] = g_value_get_double (v);
- }
- }
-
- if (self->b) {
- for (i = 0; i < self->b->n_values; i++) {
- GValue *v = g_value_array_get_nth (self->b, i);
- b[i] = g_value_get_double (v);
- }
- }
-
- gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
- (self), a, (self->a) ? self->a->n_values : 0, b,
- (self->b) ? self->b->n_values : 0);
-}
-
-static void
-gst_audio_iir_filter_init (GstAudioIIRFilter * self,
- GstAudioIIRFilterClass * g_class)
-{
- GValue v = { 0, };
- GValueArray *a, *b;
-
- a = g_value_array_new (1);
-
- g_value_init (&v, G_TYPE_DOUBLE);
- g_value_set_double (&v, 1.0);
- g_value_array_append (a, &v);
- g_value_unset (&v);
-
- b = NULL;
- gst_audio_iir_filter_update_coefficients (self, a, b);
-
- self->lock = g_mutex_new ();
-}
-
-/* GstAudioFilter vmethod implementations */
-
-/* get notified of caps and plug in the correct process function */
-static gboolean
-gst_audio_iir_filter_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (base);
-
- if (self->rate != format->rate) {
- g_signal_emit (G_OBJECT (self),
- gst_audio_iir_filter_signals[SIGNAL_RATE_CHANGED], 0, format->rate);
- self->rate = format->rate;
- }
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
-
-static void
-gst_audio_iir_filter_finalize (GObject * object)
-{
- GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (object);
-
- g_mutex_free (self->lock);
- self->lock = NULL;
-
- if (self->a)
- g_value_array_free (self->a);
- self->a = NULL;
- if (self->b)
- g_value_array_free (self->b);
- self->b = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_iir_filter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (object);
-
- g_return_if_fail (GST_IS_AUDIO_IIR_FILTER (self));
-
- switch (prop_id) {
- case PROP_A:
- g_mutex_lock (self->lock);
- gst_audio_iir_filter_update_coefficients (self, g_value_dup_boxed (value),
- NULL);
- g_mutex_unlock (self->lock);
- break;
- case PROP_B:
- g_mutex_lock (self->lock);
- gst_audio_iir_filter_update_coefficients (self, NULL,
- g_value_dup_boxed (value));
- g_mutex_unlock (self->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_iir_filter_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (object);
-
- switch (prop_id) {
- case PROP_A:
- g_value_set_boxed (value, self->a);
- break;
- case PROP_B:
- g_value_set_boxed (value, self->b);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/audiofx/audioiirfilter.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef __GST_AUDIO_IIR_FILTER_H__
-#define __GST_AUDIO_IIR_FILTER_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/audio/gstaudiofilter.h>
-
-#include "audiofxbaseiirfilter.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_IIR_FILTER \
- (gst_audio_iir_filter_get_type())
-#define GST_AUDIO_IIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_IIR_FILTER,GstAudioIIRFilter))
-#define GST_AUDIO_IIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_IIR_FILTER,GstAudioIIRFilterClass))
-#define GST_IS_AUDIO_IIR_FILTER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_IIR_FILTER))
-#define GST_IS_AUDIO_IIR_FILTER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_IIR_FILTER))
-
-typedef struct _GstAudioIIRFilter GstAudioIIRFilter;
-typedef struct _GstAudioIIRFilterClass GstAudioIIRFilterClass;
-
-/**
- * GstAudioIIRFilter:
- *
- * Opaque data structure.
- */
-struct _GstAudioIIRFilter {
- GstAudioFXBaseIIRFilter parent;
-
- GValueArray *a, *b;
-
- /* < private > */
- GMutex *lock;
- gint rate;
-};
-
-struct _GstAudioIIRFilterClass {
- GstAudioFXBaseIIRFilterClass parent;
-
- void (*rate_changed) (GstElement * element, gint rate);
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_iir_filter_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_IIR_FILTER_H__ */
--- a/gst_plugins_good/gst/audiofx/audioinvert.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audioinvert
- *
- * Swaps upper and lower half of audio samples. Mixing an inverted sample on top of
- * the original with a slight delay can produce effects that sound like resonance.
- * Creating a stereo sample from a mono source, with one channel inverted produces wide-stereo sounds.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc wave=saw ! audioinvert invert=0.4 ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audioinvert invert=0.4 ! alsasink
- * gst-launch audiotestsrc wave=saw ! audioconvert ! audioinvert invert=0.4 ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audioinvert.h"
-
-#define GST_CAT_DEFAULT gst_audio_invert_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-static const GstElementDetails element_details =
-GST_ELEMENT_DETAILS ("Audio inversion",
- "Filter/Effect/Audio",
- "Swaps upper and lower half of audio samples",
- "Sebastian Dröge <slomo@circular-chaos.org>");
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_DEGREE
-};
-
-#define ALLOWED_CAPS \
- "audio/x-raw-int," \
- " depth=(int)16," \
- " width=(int)16," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-float," \
- " width=(int)32," \
- " endianness=(int)BYTE_ORDER," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_invert_debug, "audioinvert", 0, "audioinvert element");
-
-GST_BOILERPLATE_FULL (GstAudioInvert, gst_audio_invert, GstAudioFilter,
- GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static void gst_audio_invert_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_invert_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_audio_invert_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-static GstFlowReturn gst_audio_invert_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-
-static void gst_audio_invert_transform_int (GstAudioInvert * filter,
- gint16 * data, guint num_samples);
-static void gst_audio_invert_transform_float (GstAudioInvert * filter,
- gfloat * data, guint num_samples);
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_invert_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstCaps *caps;
-
- gst_element_class_set_details (element_class, &element_details);
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_invert_class_init (GstAudioInvertClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_audio_invert_set_property;
- gobject_class->get_property = gst_audio_invert_get_property;
-
- g_object_class_install_property (gobject_class, PROP_DEGREE,
- g_param_spec_float ("degree", "Degree",
- "Degree of inversion", 0.0, 1.0,
- 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- GST_AUDIO_FILTER_CLASS (klass)->setup =
- GST_DEBUG_FUNCPTR (gst_audio_invert_setup);
- GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_invert_transform_ip);
-}
-
-static void
-gst_audio_invert_init (GstAudioInvert * filter, GstAudioInvertClass * klass)
-{
- filter->degree = 0.0;
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
- gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
-}
-
-static void
-gst_audio_invert_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioInvert *filter = GST_AUDIO_INVERT (object);
-
- switch (prop_id) {
- case PROP_DEGREE:
- filter->degree = g_value_get_float (value);
- gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter),
- filter->degree == 0.0);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_invert_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioInvert *filter = GST_AUDIO_INVERT (object);
-
- switch (prop_id) {
- case PROP_DEGREE:
- g_value_set_float (value, filter->degree);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_invert_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioInvert *filter = GST_AUDIO_INVERT (base);
- gboolean ret = TRUE;
-
- if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
- filter->process = (GstAudioInvertProcessFunc)
- gst_audio_invert_transform_float;
- else if (format->type == GST_BUFTYPE_LINEAR && format->width == 16)
- filter->process = (GstAudioInvertProcessFunc)
- gst_audio_invert_transform_int;
- else
- ret = FALSE;
-
- return ret;
-}
-
-static void
-gst_audio_invert_transform_int (GstAudioInvert * filter,
- gint16 * data, guint num_samples)
-{
- gint i;
- gfloat dry = 1.0 - filter->degree;
- glong val;
-
- for (i = 0; i < num_samples; i++) {
- val = (*data) * dry + (-1 - (*data)) * filter->degree;
- *data++ = (gint16) CLAMP (val, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_invert_transform_float (GstAudioInvert * filter,
- gfloat * data, guint num_samples)
-{
- gint i;
- gfloat dry = 1.0 - filter->degree;
- glong val;
-
- for (i = 0; i < num_samples; i++) {
- val = (*data) * dry - (*data) * filter->degree;
- *data++ = val;
- }
-}
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_invert_transform_ip (GstBaseTransform * base, GstBuffer * buf)
-{
- GstAudioInvert *filter = GST_AUDIO_INVERT (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
- if (gst_base_transform_is_passthrough (base) ||
- G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
- return GST_FLOW_OK;
-
- filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audioinvert.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_INVERT_H__
-#define __GST_AUDIO_INVERT_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_INVERT (gst_audio_invert_get_type())
-#define GST_AUDIO_INVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_INVERT,GstAudioInvert))
-#define GST_IS_AUDIO_INVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_INVERT))
-#define GST_AUDIO_INVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_INVERT,GstAudioInvertClass))
-#define GST_IS_AUDIO_INVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_INVERT))
-#define GST_AUDIO_INVERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_INVERT,GstAudioInvertClass))
-typedef struct _GstAudioInvert GstAudioInvert;
-typedef struct _GstAudioInvertClass GstAudioInvertClass;
-
-typedef void (*GstAudioInvertProcessFunc) (GstAudioInvert *, guint8 *, guint);
-
-struct _GstAudioInvert
-{
- GstAudioFilter audiofilter;
-
- gfloat degree;
-
- /* < private > */
- GstAudioInvertProcessFunc process;
-};
-
-struct _GstAudioInvertClass
-{
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_invert_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_INVERT_H__ */
--- a/gst_plugins_good/gst/audiofx/audiokaraoke.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audiokaraoke
- *
- * Remove the voice from audio by filtering the center channel.
- * This plugin is useful for karaoke applications.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audiokaraoke ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <math.h>
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiokaraoke.h"
-
-#define GST_CAT_DEFAULT gst_audio_karaoke_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-static const GstElementDetails element_details =
-GST_ELEMENT_DETAILS ("AudioKaraoke",
- "Filter/Effect/Audio",
- "Removes voice from sound",
- "Wim Taymans <wim.taymans@gmail.com>");
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_LEVEL 1.0
-#define DEFAULT_MONO_LEVEL 1.0
-#define DEFAULT_FILTER_BAND 220.0
-#define DEFAULT_FILTER_WIDTH 100.0
-
-enum
-{
- PROP_0,
- PROP_LEVEL,
- PROP_MONO_LEVEL,
- PROP_FILTER_BAND,
- PROP_FILTER_WIDTH,
- PROP_LAST
-};
-
-#define ALLOWED_CAPS \
- "audio/x-raw-int," \
- " depth=(int)16," \
- " width=(int)16," \
- " endianness=(int)BYTE_ORDER," \
- " signed=(bool)TRUE," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]; " \
- "audio/x-raw-float," \
- " width=(int)32," \
- " endianness=(int)BYTE_ORDER," \
- " rate=(int)[1,MAX]," \
- " channels=(int)[1,MAX]"
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_karaoke_debug, "audiokaraoke", 0, "audiokaraoke element");
-
-GST_BOILERPLATE_FULL (GstAudioKaraoke, gst_audio_karaoke, GstAudioFilter,
- GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
-
-static void gst_audio_karaoke_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_karaoke_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_audio_karaoke_setup (GstAudioFilter * filter,
- GstRingBufferSpec * format);
-static GstFlowReturn gst_audio_karaoke_transform_ip (GstBaseTransform * base,
- GstBuffer * buf);
-
-static void gst_audio_karaoke_transform_int (GstAudioKaraoke * filter,
- gint16 * data, guint num_samples);
-static void gst_audio_karaoke_transform_float (GstAudioKaraoke * filter,
- gfloat * data, guint num_samples);
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_karaoke_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstCaps *caps;
-
- gst_element_class_set_details (element_class, &element_details);
-
- caps = gst_caps_from_string (ALLOWED_CAPS);
- gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
- caps);
- gst_caps_unref (caps);
-}
-
-static void
-gst_audio_karaoke_class_init (GstAudioKaraokeClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_audio_karaoke_set_property;
- gobject_class->get_property = gst_audio_karaoke_get_property;
-
- g_object_class_install_property (gobject_class, PROP_LEVEL,
- g_param_spec_float ("level", "Level",
- "Level of the effect (1.0 = full)", 0.0, 1.0, DEFAULT_LEVEL,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_MONO_LEVEL,
- g_param_spec_float ("mono-level", "Mono Level",
- "Level of the mono channel (1.0 = full)", 0.0, 1.0, DEFAULT_LEVEL,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_FILTER_BAND,
- g_param_spec_float ("filter-band", "Filter Band",
- "The Frequency band of the filter", 0.0, 441.0, DEFAULT_FILTER_BAND,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- g_object_class_install_property (gobject_class, PROP_FILTER_WIDTH,
- g_param_spec_float ("filter-width", "Filter Width",
- "The Frequency width of the filter", 0.0, 100.0, DEFAULT_FILTER_WIDTH,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
- GST_AUDIO_FILTER_CLASS (klass)->setup =
- GST_DEBUG_FUNCPTR (gst_audio_karaoke_setup);
- GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
- GST_DEBUG_FUNCPTR (gst_audio_karaoke_transform_ip);
-}
-
-static void
-gst_audio_karaoke_init (GstAudioKaraoke * filter, GstAudioKaraokeClass * klass)
-{
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
- gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
-
- filter->level = DEFAULT_LEVEL;
- filter->mono_level = DEFAULT_MONO_LEVEL;
- filter->filter_band = DEFAULT_FILTER_BAND;
- filter->filter_width = DEFAULT_FILTER_WIDTH;
-}
-
-static void
-update_filter (GstAudioKaraoke * filter, gint rate)
-{
- gfloat A, B, C;
-
- if (rate == 0)
- return;
-
- C = exp (-2 * M_PI * filter->filter_width / rate);
- B = -4 * C / (1 + C) * cos (2 * M_PI * filter->filter_band / rate);
- A = sqrt (1 - B * B / (4 * C)) * (1 - C);
-
- filter->A = A;
- filter->B = B;
- filter->C = C;
- filter->y1 = 0.0;
- filter->y2 = 0.0;
-}
-
-static void
-gst_audio_karaoke_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioKaraoke *filter;
-
- filter = GST_AUDIO_KARAOKE (object);
-
- switch (prop_id) {
- case PROP_LEVEL:
- filter->level = g_value_get_float (value);
- break;
- case PROP_MONO_LEVEL:
- filter->mono_level = g_value_get_float (value);
- break;
- case PROP_FILTER_BAND:
- filter->filter_band = g_value_get_float (value);
- update_filter (filter, filter->rate);
- break;
- case PROP_FILTER_WIDTH:
- filter->filter_width = g_value_get_float (value);
- update_filter (filter, filter->rate);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_karaoke_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioKaraoke *filter;
-
- filter = GST_AUDIO_KARAOKE (object);
-
- switch (prop_id) {
- case PROP_LEVEL:
- g_value_set_float (value, filter->level);
- break;
- case PROP_MONO_LEVEL:
- g_value_set_float (value, filter->mono_level);
- break;
- case PROP_FILTER_BAND:
- g_value_set_float (value, filter->filter_band);
- break;
- case PROP_FILTER_WIDTH:
- g_value_set_float (value, filter->filter_width);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_karaoke_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioKaraoke *filter = GST_AUDIO_KARAOKE (base);
- gboolean ret = TRUE;
-
- filter->channels = format->channels;
- filter->rate = format->rate;
-
- if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
- filter->process = (GstAudioKaraokeProcessFunc)
- gst_audio_karaoke_transform_float;
- else if (format->type == GST_BUFTYPE_LINEAR && format->width == 16)
- filter->process = (GstAudioKaraokeProcessFunc)
- gst_audio_karaoke_transform_int;
- else
- ret = FALSE;
-
- update_filter (filter, format->rate);
-
- return ret;
-}
-
-static void
-gst_audio_karaoke_transform_int (GstAudioKaraoke * filter,
- gint16 * data, guint num_samples)
-{
- gint i, l, r, o, x;
- gint channels;
- gdouble y;
- gint level;
-
- channels = filter->channels;
- level = filter->level * 256;
-
- for (i = 0; i < num_samples; i += channels) {
- /* get left and right inputs */
- l = data[i];
- r = data[i + 1];
- /* do filtering */
- x = (l + r) / 2;
- y = (filter->A * x - filter->B * filter->y1) - filter->C * filter->y2;
- filter->y2 = filter->y1;
- filter->y1 = y;
- /* filter mono signal */
- o = (int) (y * filter->mono_level);
- o = CLAMP (o, G_MININT16, G_MAXINT16);
- o = (o * level) >> 8;
- /* now cut the center */
- x = l - ((r * level) >> 8) + o;
- r = r - ((l * level) >> 8) + o;
- data[i] = CLAMP (x, G_MININT16, G_MAXINT16);
- data[i + 1] = CLAMP (r, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_karaoke_transform_float (GstAudioKaraoke * filter,
- gfloat * data, guint num_samples)
-{
- gint i;
- gint channels;
- gdouble l, r, o;
- gdouble y;
-
- channels = filter->channels;
-
- for (i = 0; i < num_samples; i += channels) {
- /* get left and right inputs */
- l = data[i];
- r = data[i + 1];
- /* do filtering */
- y = (filter->A * ((l + r) / 2.0) - filter->B * filter->y1) -
- filter->C * filter->y2;
- filter->y2 = filter->y1;
- filter->y1 = y;
- /* filter mono signal */
- o = y * filter->mono_level * filter->level;
- /* now cut the center */
- data[i] = l - (r * filter->level) + o;
- data[i + 1] = r - (l * filter->level) + o;
- }
-}
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_karaoke_transform_ip (GstBaseTransform * base, GstBuffer * buf)
-{
- GstAudioKaraoke *filter = GST_AUDIO_KARAOKE (base);
- guint num_samples =
- GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
- if (gst_base_transform_is_passthrough (base) ||
- G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
- return GST_FLOW_OK;
-
- filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audiokaraoke.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_KARAOKE_H__
-#define __GST_AUDIO_KARAOKE_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_KARAOKE (gst_audio_karaoke_get_type())
-#define GST_AUDIO_KARAOKE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_KARAOKE,GstAudioKaraoke))
-#define GST_IS_AUDIO_KARAOKE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_KARAOKE))
-#define GST_AUDIO_KARAOKE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_KARAOKE,GstAudioKaraokeClass))
-#define GST_IS_AUDIO_KARAOKE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_KARAOKE))
-#define GST_AUDIO_KARAOKE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_KARAOKE,GstAudioKaraokeClass))
-typedef struct _GstAudioKaraoke GstAudioKaraoke;
-typedef struct _GstAudioKaraokeClass GstAudioKaraokeClass;
-
-typedef void (*GstAudioKaraokeProcessFunc) (GstAudioKaraoke *, guint8 *, guint);
-
-struct _GstAudioKaraoke
-{
- GstAudioFilter audiofilter;
-
- gint channels;
- gint rate;
-
- /* properties */
- gfloat level;
- gfloat mono_level;
- gfloat filter_band;
- gfloat filter_width;
-
- /* filter coef */
- gfloat A, B, C;
- gfloat y1, y2;
-
- /* < private > */
- GstAudioKaraokeProcessFunc process;
-};
-
-struct _GstAudioKaraokeClass
-{
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_karaoke_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_KARAOKE_H__ */
--- a/gst_plugins_good/gst/audiofx/audiopanorama.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,648 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) 2006 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-audiopanorama
- *
- * Stereo panorama effect with controllable pan position. One can choose between the default psychoacoustic panning method,
- * which keeps the same perceived loudness, and a simple panning method that just controls the volume on one channel.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc wave=saw ! audiopanorama panorama=-1.00 ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiopanorama panorama=-1.00 ! alsasink
- * gst-launch audiotestsrc wave=saw ! audioconvert ! audiopanorama panorama=-1.00 ! audioconvert ! alsasink
- * gst-launch audiotestsrc wave=saw ! audioconvert ! audiopanorama method=simple panorama=-0.50 ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiopanorama.h"
-
-#define GST_CAT_DEFAULT gst_audio_panorama_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-static const GstElementDetails element_details =
-GST_ELEMENT_DETAILS ("Stereo positioning",
- "Filter/Effect/Audio",
- "Positions audio streams in the stereo panorama",
- "Stefan Kost <ensonic@users.sf.net>");
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_PANORAMA,
- PROP_METHOD
-};
-
-enum
-{
- METHOD_PSYCHOACOUSTIC = 0,
- METHOD_SIMPLE,
- NUM_METHODS
-};
-
-#define GST_TYPE_AUDIO_PANORAMA_METHOD (gst_audio_panorama_method_get_type ())
-static GType
-gst_audio_panorama_method_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {METHOD_PSYCHOACOUSTIC, "Psychoacoustic Panning (default)",
- "psychoacoustic"},
- {METHOD_SIMPLE, "Simple Panning", "simple"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioPanoramaMethod", values);
- }
- return gtype;
-}
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-float, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, " "width = (int) 32; "
- "audio/x-raw-int, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
- );
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-float, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) 2, "
- "endianness = (int) BYTE_ORDER, " "width = (int) 32; "
- "audio/x-raw-int, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) 2, "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
- );
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_panorama_debug, "audiopanorama", 0, "audiopanorama element");
-
-GST_BOILERPLATE_FULL (GstAudioPanorama, gst_audio_panorama, GstBaseTransform,
- GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
-
-static void gst_audio_panorama_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_panorama_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_audio_panorama_get_unit_size (GstBaseTransform * base,
- GstCaps * caps, guint * size);
-static GstCaps *gst_audio_panorama_transform_caps (GstBaseTransform * base,
- GstPadDirection direction, GstCaps * caps);
-static gboolean gst_audio_panorama_set_caps (GstBaseTransform * base,
- GstCaps * incaps, GstCaps * outcaps);
-
-static void gst_audio_panorama_transform_m2s_int (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_int (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_m2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples);
-
-static void gst_audio_panorama_transform_m2s_int_simple (GstAudioPanorama *
- filter, gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_int_simple (GstAudioPanorama *
- filter, gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_m2s_float_simple (GstAudioPanorama *
- filter, gfloat * idata, gfloat * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_float_simple (GstAudioPanorama *
- filter, gfloat * idata, gfloat * odata, guint num_samples);
-
-static GstFlowReturn gst_audio_panorama_transform (GstBaseTransform * base,
- GstBuffer * inbuf, GstBuffer * outbuf);
-
-
-/* Table with processing functions: [channels][format][method] */
-static GstAudioPanoramaProcessFunc panorama_process_functions[2][2][2] = {
- {
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_m2s_int,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_m2s_int_simple},
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_m2s_float,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_m2s_float_simple}
- },
- {
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_s2s_int,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_s2s_int_simple},
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_s2s_float,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_s2s_float_simple}
- }
-};
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_panorama_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_set_details (element_class, &element_details);
-}
-
-static void
-gst_audio_panorama_class_init (GstAudioPanoramaClass * klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_audio_panorama_set_property;
- gobject_class->get_property = gst_audio_panorama_get_property;
-
- g_object_class_install_property (gobject_class, PROP_PANORAMA,
- g_param_spec_float ("panorama", "Panorama",
- "Position in stereo panorama (-1.0 left -> 1.0 right)", -1.0, 1.0,
- 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
- /**
- * GstAudioPanorama:method
- *
- * Panning method: psychoacoustic mode keeps the same perceived loudness,
- * while simple mode just controls the volume of one channel. It's merely
- * a matter of taste which method should be chosen.
- *
- * Since: 0.10.6
- **/
- g_object_class_install_property (gobject_class, PROP_METHOD,
- g_param_spec_enum ("method", "Panning method",
- "Psychoacoustic mode keeps same perceived loudness, "
- "simple mode just controls volume of one channel.",
- GST_TYPE_AUDIO_PANORAMA_METHOD, METHOD_PSYCHOACOUSTIC,
- G_PARAM_READWRITE));
-
- GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
- GST_DEBUG_FUNCPTR (gst_audio_panorama_get_unit_size);
- GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
- GST_DEBUG_FUNCPTR (gst_audio_panorama_transform_caps);
- GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
- GST_DEBUG_FUNCPTR (gst_audio_panorama_set_caps);
- GST_BASE_TRANSFORM_CLASS (klass)->transform =
- GST_DEBUG_FUNCPTR (gst_audio_panorama_transform);
-}
-
-static void
-gst_audio_panorama_init (GstAudioPanorama * filter,
- GstAudioPanoramaClass * klass)
-{
-
- filter->panorama = 0;
- filter->method = METHOD_PSYCHOACOUSTIC;
- filter->width = 0;
- filter->channels = 0;
- filter->format_float = FALSE;
- filter->process = NULL;
-
- gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
-}
-
-static gboolean
-gst_audio_panorama_set_process_function (GstAudioPanorama * filter)
-{
- gint channel_index, format_index, method_index;
-
- /* set processing function */
- channel_index = filter->channels - 1;
- if (channel_index > 1 || channel_index < 0) {
- filter->process = NULL;
- return FALSE;
- }
-
- format_index = (filter->format_float) ? 1 : 0;
-
- method_index = filter->method;
- if (method_index >= NUM_METHODS || method_index < 0)
- method_index = METHOD_PSYCHOACOUSTIC;
-
- filter->process =
- panorama_process_functions[channel_index][format_index][method_index];
- return TRUE;
-}
-
-static void
-gst_audio_panorama_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioPanorama *filter = GST_AUDIO_PANORAMA (object);
-
- switch (prop_id) {
- case PROP_PANORAMA:
- filter->panorama = g_value_get_float (value);
- break;
- case PROP_METHOD:
- filter->method = g_value_get_enum (value);
- gst_audio_panorama_set_process_function (filter);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_panorama_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioPanorama *filter = GST_AUDIO_PANORAMA (object);
-
- switch (prop_id) {
- case PROP_PANORAMA:
- g_value_set_float (value, filter->panorama);
- break;
- case PROP_METHOD:
- g_value_set_enum (value, filter->method);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstBaseTransform vmethod implementations */
-
-static gboolean
-gst_audio_panorama_get_unit_size (GstBaseTransform * base, GstCaps * caps,
- guint * size)
-{
- gint width, channels;
- GstStructure *structure;
- gboolean ret;
-
- g_assert (size);
-
- /* this works for both float and int */
- structure = gst_caps_get_structure (caps, 0);
- ret = gst_structure_get_int (structure, "width", &width);
- ret &= gst_structure_get_int (structure, "channels", &channels);
-
- *size = width * channels / 8;
-
- return ret;
-}
-
-static GstCaps *
-gst_audio_panorama_transform_caps (GstBaseTransform * base,
- GstPadDirection direction, GstCaps * caps)
-{
- GstCaps *res;
- GstStructure *structure;
-
- /* transform caps gives one single caps so we can just replace
- * the channel property with our range. */
- res = gst_caps_copy (caps);
- structure = gst_caps_get_structure (res, 0);
- if (direction == GST_PAD_SRC) {
- GST_INFO ("allow 1-2 channels");
- gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
- } else {
- GST_INFO ("allow 2 channels");
- gst_structure_set (structure, "channels", G_TYPE_INT, 2, NULL);
- }
-
- return res;
-}
-
-static gboolean
-gst_audio_panorama_set_caps (GstBaseTransform * base, GstCaps * incaps,
- GstCaps * outcaps)
-{
- GstAudioPanorama *filter = GST_AUDIO_PANORAMA (base);
- const GstStructure *structure;
- gboolean ret;
- gint width;
- const gchar *fmt;
-
- /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */
-
- structure = gst_caps_get_structure (incaps, 0);
- ret = gst_structure_get_int (structure, "channels", &filter->channels);
- if (!ret)
- goto no_channels;
-
- ret = gst_structure_get_int (structure, "width", &width);
- if (!ret)
- goto no_width;
- filter->width = width / 8;
-
- fmt = gst_structure_get_name (structure);
- if (!strcmp (fmt, "audio/x-raw-int"))
- filter->format_float = FALSE;
- else
- filter->format_float = TRUE;
-
- GST_DEBUG ("try to process %s input with %d channels", fmt, filter->channels);
-
- ret = gst_audio_panorama_set_process_function (filter);
-
- if (!ret)
- GST_WARNING ("can't process input with %d channels", filter->channels);
-
- return ret;
-
-no_channels:
- GST_DEBUG ("no channels in caps");
- return ret;
-no_width:
- GST_DEBUG ("no width in caps");
- return ret;
-}
-
-/* psychoacoustic processing functions */
-static void
-gst_audio_panorama_transform_m2s_int (GstAudioPanorama * filter, gint16 * idata,
- gint16 * odata, guint num_samples)
-{
- guint i;
- gdouble val;
- glong lval, rval;
- gdouble rpan, lpan;
-
- /* pan: -1.0 0.0 1.0
- * lpan: 1.0 0.5 0.0
- * rpan: 0.0 0.5 1.0
- *
- * FIXME: we should use -3db (1/sqtr(2)) for 50:50
- */
- rpan = (gdouble) (filter->panorama + 1.0) / 2.0;
- lpan = 1.0 - rpan;
-
- for (i = 0; i < num_samples; i++) {
- val = (gdouble) * idata++;
-
- lval = (glong) (val * lpan);
- rval = (glong) (val * rpan);
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_panorama_transform_s2s_int (GstAudioPanorama * filter, gint16 * idata,
- gint16 * odata, guint num_samples)
-{
- guint i;
- glong lval, rval;
- gdouble lival, rival;
- gdouble lrpan, llpan, rrpan, rlpan;
-
- /* pan: -1.0 0.0 1.0
- * llpan: 1.0 1.0 0.0
- * lrpan: 1.0 0.0 0.0
- * rrpan: 0.0 1.0 1.0
- * rlpan: 0.0 0.0 1.0
- */
- if (filter->panorama > 0) {
- rlpan = (gdouble) filter->panorama;
- llpan = 1.0 - rlpan;
- lrpan = 0.0;
- rrpan = 1.0;
- } else {
- rrpan = (gdouble) (1.0 + filter->panorama);
- lrpan = 1.0 - rrpan;
- rlpan = 0.0;
- llpan = 1.0;
- }
-
- for (i = 0; i < num_samples; i++) {
- lival = (gdouble) * idata++;
- rival = (gdouble) * idata++;
-
- lval = lival * llpan + rival * lrpan;
- rval = lival * rlpan + rival * rrpan;
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_panorama_transform_m2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
-{
- guint i;
- gfloat val;
- gdouble rpan, lpan;
-
- /* pan: -1.0 0.0 1.0
- * lpan: 1.0 0.5 0.0
- * rpan: 0.0 0.5 1.0
- *
- * FIXME: we should use -3db (1/sqtr(2)) for 50:50
- */
- rpan = (gdouble) (filter->panorama + 1.0) / 2.0;
- lpan = 1.0 - rpan;
-
- for (i = 0; i < num_samples; i++) {
- val = *idata++;
-
- *odata++ = val * lpan;
- *odata++ = val * rpan;
- }
-}
-
-static void
-gst_audio_panorama_transform_s2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
-{
- guint i;
- gfloat lival, rival;
- gdouble lrpan, llpan, rrpan, rlpan;
-
- /* pan: -1.0 0.0 1.0
- * llpan: 1.0 1.0 0.0
- * lrpan: 1.0 0.0 0.0
- * rrpan: 0.0 1.0 1.0
- * rlpan: 0.0 0.0 1.0
- */
- if (filter->panorama > 0) {
- rlpan = (gdouble) filter->panorama;
- llpan = 1.0 - rlpan;
- lrpan = 0.0;
- rrpan = 1.0;
- } else {
- rrpan = (gdouble) (1.0 + filter->panorama);
- lrpan = 1.0 - rrpan;
- rlpan = 0.0;
- llpan = 1.0;
- }
-
- for (i = 0; i < num_samples; i++) {
- lival = *idata++;
- rival = *idata++;
-
- *odata++ = lival * llpan + rival * lrpan;
- *odata++ = lival * rlpan + rival * rrpan;
- }
-}
-
-/* simple processing functions */
-static void
-gst_audio_panorama_transform_m2s_int_simple (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples)
-{
- guint i;
- gdouble val;
- glong lval, rval;
-
- for (i = 0; i < num_samples; i++) {
- val = (gdouble) * idata++;
-
- if (filter->panorama > 0.0) {
- lval = (glong) (val * (1.0 - filter->panorama));
- rval = (glong) val;
- } else {
- lval = (glong) val;
- rval = (glong) (val * (1.0 + filter->panorama));
- }
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_panorama_transform_s2s_int_simple (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples)
-{
- guint i;
- glong lval, rval;
- gdouble lival, rival;
-
- for (i = 0; i < num_samples; i++) {
- lival = (gdouble) * idata++;
- rival = (gdouble) * idata++;
-
- if (filter->panorama > 0.0) {
- lval = (glong) (lival * (1.0 - filter->panorama));
- rval = (glong) rival;
- } else {
- lval = (glong) lival;
- rval = (glong) (rival * (1.0 + filter->panorama));
- }
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
-}
-
-static void
-gst_audio_panorama_transform_m2s_float_simple (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
-{
- guint i;
- gfloat val;
-
-
- for (i = 0; i < num_samples; i++) {
- val = *idata++;
-
- if (filter->panorama > 0.0) {
- *odata++ = val * (1.0 - filter->panorama);
- *odata++ = val;
- } else {
- *odata++ = val;
- *odata++ = val * (1.0 + filter->panorama);
- }
- }
-}
-
-static void
-gst_audio_panorama_transform_s2s_float_simple (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
-{
- guint i;
- gfloat lival, rival;
-
- for (i = 0; i < num_samples; i++) {
- lival = *idata++;
- rival = *idata++;
-
- if (filter->panorama > 0.0) {
- *odata++ = lival * (1.0 - filter->panorama);
- *odata++ = rival;
- } else {
- *odata++ = lival;
- *odata++ = rival * (1.0 + filter->panorama);
- }
- }
-}
-
-/* this function does the actual processing
- */
-static GstFlowReturn
-gst_audio_panorama_transform (GstBaseTransform * base, GstBuffer * inbuf,
- GstBuffer * outbuf)
-{
- GstAudioPanorama *filter = GST_AUDIO_PANORAMA (base);
- guint num_samples = GST_BUFFER_SIZE (outbuf) / (2 * filter->width);
-
- if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (outbuf)))
- gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (outbuf));
-
- if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
- memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
- return GST_FLOW_OK;
- }
-
- filter->process (filter, GST_BUFFER_DATA (inbuf),
- GST_BUFFER_DATA (outbuf), num_samples);
-
- return GST_FLOW_OK;
-}
--- a/gst_plugins_good/gst/audiofx/audiopanorama.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUDIO_PANORAMA_H__
-#define __GST_AUDIO_PANORAMA_H__
-
-#include <gst/gst.h>
-#include <gst/gst_global.h>
-#include <gst/base/gstbasetransform.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_PANORAMA (gst_audio_panorama_get_type())
-#define GST_AUDIO_PANORAMA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_PANORAMA,GstAudioPanorama))
-#define GST_IS_AUDIO_PANORAMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_PANORAMA))
-#define GST_AUDIO_PANORAMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_AUDIO_PANORAMA,GstAudioPanoramaClass))
-#define GST_IS_AUDIO_PANORAMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_AUDIO_PANORAMA))
-#define GST_AUDIO_PANORAMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_AUDIO_PANORAMA,GstAudioPanoramaClass))
-
-typedef struct _GstAudioPanorama GstAudioPanorama;
-typedef struct _GstAudioPanoramaClass GstAudioPanoramaClass;
-
-typedef void (*GstAudioPanoramaProcessFunc)(GstAudioPanorama*, guint8*, guint8*, guint);
-
-struct _GstAudioPanorama {
- GstBaseTransform element;
-
- gfloat panorama;
-
- /* < private > */
- GstAudioPanoramaProcessFunc process;
- gint channels;
- gboolean format_float;
- gint width;
- gint method;
-};
-
-struct _GstAudioPanoramaClass {
- GstBaseTransformClass parent_class;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_panorama_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_PANORAMA_H__ */
--- a/gst_plugins_good/gst/audiofx/audiowsincband.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,440 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- *
- * this windowed sinc filter is taken from the freely downloadable DSP book,
- * "The Scientist and Engineer's Guide to Digital Signal Processing",
- * chapter 16
- * available at http://www.dspguide.com/
- *
- */
-
-/**
- * SECTION:element-audiowsincband
- *
- * Attenuates all frequencies outside (bandpass) or inside (bandreject) of a frequency
- * band. The length parameter controls the rolloff, the window parameter
- * controls rolloff and stopband attenuation. The Hamming window provides a faster rolloff but a bit
- * worse stopband attenuation, the other way around for the Blackman window.
- *
- * This element has the advantage over the Chebyshev bandpass and bandreject filter that it has
- * a much better rolloff when using a larger kernel size and almost linear phase. The only
- * disadvantage is the much slower execution time with larger kernels.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc freq=1500 ! audioconvert ! audiosincband mode=band-pass lower-frequency=3000 upper-frequency=10000 length=501 window=blackman ! audioconvert ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiowsincband mode=band-reject lower-frequency=59 upper-frequency=61 length=10001 window=hamming ! audioconvert ! alsasink
- * gst-launch audiotestsrc wave=white-noise ! audioconvert ! audiowsincband mode=band-pass lower-frequency=1000 upper-frequency=2000 length=31 ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiowsincband.h"
-
-#define GST_CAT_DEFAULT gst_gst_audio_wsincband_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- PROP_0,
- PROP_LENGTH,
- PROP_LOWER_FREQUENCY,
- PROP_UPPER_FREQUENCY,
- PROP_MODE,
- PROP_WINDOW
-};
-
-enum
-{
- MODE_BAND_PASS = 0,
- MODE_BAND_REJECT
-};
-
-#define GST_TYPE_AUDIO_WSINC_BAND_MODE (gst_gst_audio_wsincband_mode_get_type ())
-static GType
-gst_gst_audio_wsincband_mode_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {MODE_BAND_PASS, "Band pass (default)",
- "band-pass"},
- {MODE_BAND_REJECT, "Band reject",
- "band-reject"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioWSincBandMode", values);
- }
- return gtype;
-}
-
-enum
-{
- WINDOW_HAMMING = 0,
- WINDOW_BLACKMAN
-};
-
-#define GST_TYPE_AUDIO_WSINC_BAND_WINDOW (gst_gst_audio_wsincband_window_get_type ())
-static GType
-gst_gst_audio_wsincband_window_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {WINDOW_HAMMING, "Hamming window (default)",
- "hamming"},
- {WINDOW_BLACKMAN, "Blackman window",
- "blackman"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioWSincBandWindow", values);
- }
- return gtype;
-}
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_gst_audio_wsincband_debug, "audiowsincband", 0, \
- "Band-pass and Band-reject Windowed sinc filter plugin");
-
-GST_BOILERPLATE_FULL (GstAudioWSincBand, gst_audio_wsincband, GstAudioFilter,
- GST_TYPE_AUDIO_FX_BASE_FIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_wsincband_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_wsincband_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_audio_wsincband_finalize (GObject * object);
-
-static gboolean gst_audio_wsincband_setup (GstAudioFilter * base,
- GstRingBufferSpec * format);
-
-/* Element class */
-static void
-gst_audio_wsincband_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "Band pass & band reject filter", "Filter/Effect/Audio",
- "Band pass and band reject windowed sinc filter",
- "Thomas Vander Stichele <thomas at apestaart dot org>, "
- "Steven W. Smith, "
- "Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>, "
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_wsincband_class_init (GstAudioWSincBandClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_wsincband_set_property;
- gobject_class->get_property = gst_audio_wsincband_get_property;
- gobject_class->finalize = gst_audio_wsincband_finalize;
-
- /* FIXME: Don't use the complete possible range but restrict the upper boundary
- * so automatically generated UIs can use a slider */
- g_object_class_install_property (gobject_class, PROP_LOWER_FREQUENCY,
- g_param_spec_float ("lower-frequency", "Lower Frequency",
- "Cut-off lower frequency (Hz)", 0.0, 100000.0, 0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_UPPER_FREQUENCY,
- g_param_spec_float ("upper-frequency", "Upper Frequency",
- "Cut-off upper frequency (Hz)", 0.0, 100000.0, 0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_LENGTH,
- g_param_spec_int ("length", "Length",
- "Filter kernel length, will be rounded to the next odd number", 3,
- 50000, 101,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_MODE,
- g_param_spec_enum ("mode", "Mode",
- "Band pass or band reject mode", GST_TYPE_AUDIO_WSINC_BAND_MODE,
- MODE_BAND_PASS,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_WINDOW,
- g_param_spec_enum ("window", "Window",
- "Window function to use", GST_TYPE_AUDIO_WSINC_BAND_WINDOW,
- WINDOW_HAMMING,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_wsincband_setup);
-}
-
-static void
-gst_audio_wsincband_init (GstAudioWSincBand * self,
- GstAudioWSincBandClass * g_class)
-{
- self->kernel_length = 101;
- self->lower_frequency = 0.0;
- self->upper_frequency = 0.0;
- self->mode = MODE_BAND_PASS;
- self->window = WINDOW_HAMMING;
-
- self->lock = g_mutex_new ();
-}
-
-static void
-gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
-{
- gint i = 0;
- gdouble sum = 0.0;
- gint len = 0;
- gdouble *kernel_lp, *kernel_hp;
- gdouble w;
- gdouble *kernel;
-
- len = self->kernel_length;
-
- if (GST_AUDIO_FILTER (self)->format.rate == 0) {
- GST_DEBUG ("rate not set yet");
- return;
- }
-
- if (GST_AUDIO_FILTER (self)->format.channels == 0) {
- GST_DEBUG ("channels not set yet");
- return;
- }
-
- /* Clamp frequencies */
- self->lower_frequency =
- CLAMP (self->lower_frequency, 0.0,
- GST_AUDIO_FILTER (self)->format.rate / 2);
- self->upper_frequency =
- CLAMP (self->upper_frequency, 0.0,
- GST_AUDIO_FILTER (self)->format.rate / 2);
- if (self->lower_frequency > self->upper_frequency) {
- gint tmp = self->lower_frequency;
-
- self->lower_frequency = self->upper_frequency;
- self->upper_frequency = tmp;
- }
-
- GST_DEBUG ("gst_audio_wsincband: initializing filter kernel of length %d "
- "with lower frequency %.2lf Hz "
- ", upper frequency %.2lf Hz for mode %s",
- len, self->lower_frequency, self->upper_frequency,
- (self->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject");
-
- /* fill the lp kernel */
- w = 2 * M_PI * (self->lower_frequency / GST_AUDIO_FILTER (self)->format.rate);
- kernel_lp = g_new (gdouble, len);
- for (i = 0; i < len; ++i) {
- if (i == len / 2)
- kernel_lp[i] = w;
- else
- kernel_lp[i] = sin (w * (i - len / 2))
- / (i - len / 2);
- /* Windowing */
- if (self->window == WINDOW_HAMMING)
- kernel_lp[i] *= (0.54 - 0.46 * cos (2 * M_PI * i / len));
- else
- kernel_lp[i] *=
- (0.42 - 0.5 * cos (2 * M_PI * i / len) +
- 0.08 * cos (4 * M_PI * i / len));
- }
-
- /* normalize for unity gain at DC */
- sum = 0.0;
- for (i = 0; i < len; ++i)
- sum += kernel_lp[i];
- for (i = 0; i < len; ++i)
- kernel_lp[i] /= sum;
-
- /* fill the hp kernel */
- w = 2 * M_PI * (self->upper_frequency / GST_AUDIO_FILTER (self)->format.rate);
- kernel_hp = g_new (gdouble, len);
- for (i = 0; i < len; ++i) {
- if (i == len / 2)
- kernel_hp[i] = w;
- else
- kernel_hp[i] = sin (w * (i - len / 2))
- / (i - len / 2);
- /* Windowing */
- if (self->window == WINDOW_HAMMING)
- kernel_hp[i] *= (0.54 - 0.46 * cos (2 * M_PI * i / len));
- else
- kernel_hp[i] *=
- (0.42 - 0.5 * cos (2 * M_PI * i / len) +
- 0.08 * cos (4 * M_PI * i / len));
- }
-
- /* normalize for unity gain at DC */
- sum = 0.0;
- for (i = 0; i < len; ++i)
- sum += kernel_hp[i];
- for (i = 0; i < len; ++i)
- kernel_hp[i] /= sum;
-
- /* do spectral inversion to go from lowpass to highpass */
- for (i = 0; i < len; ++i)
- kernel_hp[i] = -kernel_hp[i];
- kernel_hp[len / 2] += 1;
-
- /* combine the two kernels */
- kernel = g_new (gdouble, len);
-
- for (i = 0; i < len; ++i)
- kernel[i] = kernel_lp[i] + kernel_hp[i];
-
- /* free the helper kernels */
- g_free (kernel_lp);
- g_free (kernel_hp);
-
- /* do spectral inversion to go from bandreject to bandpass
- * if specified */
- if (self->mode == MODE_BAND_PASS) {
- for (i = 0; i < len; ++i)
- kernel[i] = -kernel[i];
- kernel[len / 2] += 1;
- }
-
- gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self),
- kernel, self->kernel_length, (len - 1) / 2);
-}
-
-/* GstAudioFilter vmethod implementations */
-
-/* get notified of caps and plug in the correct process function */
-static gboolean
-gst_audio_wsincband_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (base);
-
- gst_audio_wsincband_build_kernel (self);
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
-
-static void
-gst_audio_wsincband_finalize (GObject * object)
-{
- GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (object);
-
- g_mutex_free (self->lock);
- self->lock = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_wsincband_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (object);
-
- g_return_if_fail (GST_IS_AUDIO_WSINC_BAND (self));
-
- switch (prop_id) {
- case PROP_LENGTH:{
- gint val;
-
- g_mutex_lock (self->lock);
- val = g_value_get_int (value);
- if (val % 2 == 0)
- val++;
-
- if (val != self->kernel_length) {
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
- self->kernel_length = val;
- gst_audio_wsincband_build_kernel (self);
- }
- g_mutex_unlock (self->lock);
- break;
- }
- case PROP_LOWER_FREQUENCY:
- g_mutex_lock (self->lock);
- self->lower_frequency = g_value_get_float (value);
- gst_audio_wsincband_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- case PROP_UPPER_FREQUENCY:
- g_mutex_lock (self->lock);
- self->upper_frequency = g_value_get_float (value);
- gst_audio_wsincband_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- case PROP_MODE:
- g_mutex_lock (self->lock);
- self->mode = g_value_get_enum (value);
- gst_audio_wsincband_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- case PROP_WINDOW:
- g_mutex_lock (self->lock);
- self->window = g_value_get_enum (value);
- gst_audio_wsincband_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_wsincband_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (object);
-
- switch (prop_id) {
- case PROP_LENGTH:
- g_value_set_int (value, self->kernel_length);
- break;
- case PROP_LOWER_FREQUENCY:
- g_value_set_float (value, self->lower_frequency);
- break;
- case PROP_UPPER_FREQUENCY:
- g_value_set_float (value, self->upper_frequency);
- break;
- case PROP_MODE:
- g_value_set_enum (value, self->mode);
- break;
- case PROP_WINDOW:
- g_value_set_enum (value, self->window);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/audiofx/audiowsincband.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- *
- * this windowed sinc filter is taken from the freely downloadable DSP book,
- * "The Scientist and Engineer's Guide to Digital Signal Processing",
- * chapter 16
- * available at http://www.dspguide.com/
- *
- */
-
-#ifndef __GST_AUDIO_WSINC_BAND_H__
-#define __GST_AUDIO_WSINC_BAND_H__
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/gst_global.h>
-
-#include "audiofxbasefirfilter.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_WSINC_BAND \
- (gst_audio_wsincband_get_type())
-#define GST_AUDIO_WSINC_BAND(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_WSINC_BAND,GstAudioWSincBand))
-#define GST_AUDIO_WSINC_BAND_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_WSINC_BAND,GstAudioWSincBandClass))
-#define GST_IS_AUDIO_WSINC_BAND(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_WSINC_BAND))
-#define GST_IS_AUDIO_WSINC_BAND_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_WSINC_BAND))
-
-typedef struct _GstAudioWSincBand GstAudioWSincBand;
-typedef struct _GstAudioWSincBandClass GstAudioWSincBandClass;
-
-/**
- * GstAudioWSincBand:
- *
- * Opaque data structure.
- */
-struct _GstAudioWSincBand {
- GstAudioFXBaseFIRFilter parent;
-
- gint mode;
- gint window;
- gfloat lower_frequency, upper_frequency;
- gint kernel_length; /* length of the filter kernel */
-
- /* < private > */
- GMutex *lock;
-};
-
-struct _GstAudioWSincBandClass {
- GstAudioFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_wsincband_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_WSINC_BAND_H__ */
--- a/gst_plugins_good/gst/audiofx/audiowsinclimit.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- *
- * this windowed sinc filter is taken from the freely downloadable DSP book,
- * "The Scientist and Engineer's Guide to Digital Signal Processing",
- * chapter 16
- * available at http://www.dspguide.com/
- *
- */
-
-/**
- * SECTION:element-audiowsinclimit
- *
- * Attenuates all frequencies above the cutoff frequency (low-pass) or all frequencies below the
- * cutoff frequency (high-pass). The length parameter controls the rolloff, the window parameter
- * controls rolloff and stopband attenuation. The Hamming window provides a faster rolloff but a bit
- * worse stopband attenuation, the other way around for the Blackman window.
- *
- * This element has the advantage over the Chebyshev lowpass and highpass filter that it has
- * a much better rolloff when using a larger kernel size and almost linear phase. The only
- * disadvantage is the much slower execution time with larger kernels.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc freq=1500 ! audioconvert ! audiowsinclimit mode=low-pass frequency=1000 length=501 ! audioconvert ! alsasink
- * gst-launch filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiowsinclimit mode=high-pass frequency=15000 length=501 ! audioconvert ! alsasink
- * gst-launch audiotestsrc wave=white-noise ! audioconvert ! audiowsinclimit mode=low-pass frequency=1000 length=10001 window=blackman ! audioconvert ! alsasink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "audiowsinclimit.h"
-
-#define GST_CAT_DEFAULT gst_audio_wsinclimit_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
- PROP_0,
- PROP_LENGTH,
- PROP_FREQUENCY,
- PROP_MODE,
- PROP_WINDOW
-};
-
-enum
-{
- MODE_LOW_PASS = 0,
- MODE_HIGH_PASS
-};
-
-#define GST_TYPE_AUDIO_WSINC_LIMIT_MODE (gst_audio_wsinclimit_mode_get_type ())
-static GType
-gst_audio_wsinclimit_mode_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {MODE_LOW_PASS, "Low pass (default)",
- "low-pass"},
- {MODE_HIGH_PASS, "High pass",
- "high-pass"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioWSincLimitMode", values);
- }
- return gtype;
-}
-
-enum
-{
- WINDOW_HAMMING = 0,
- WINDOW_BLACKMAN
-};
-
-#define GST_TYPE_AUDIO_WSINC_LIMIT_WINDOW (gst_audio_wsinclimit_window_get_type ())
-static GType
-gst_audio_wsinclimit_window_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {WINDOW_HAMMING, "Hamming window (default)",
- "hamming"},
- {WINDOW_BLACKMAN, "Blackman window",
- "blackman"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioWSincLimitWindow", values);
- }
- return gtype;
-}
-
-#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_audio_wsinclimit_debug, "audiowsinclimit", 0, \
- "Low-pass and High-pass Windowed sinc filter plugin");
-
-GST_BOILERPLATE_FULL (GstAudioWSincLimit, gst_audio_wsinclimit, GstAudioFilter,
- GST_TYPE_AUDIO_FX_BASE_FIR_FILTER, DEBUG_INIT);
-
-static void gst_audio_wsinclimit_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_audio_wsinclimit_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_audio_wsinclimit_finalize (GObject * object);
-
-static gboolean gst_audio_wsinclimit_setup (GstAudioFilter * base,
- GstRingBufferSpec * format);
-
-/* Element class */
-
-static void
-gst_audio_wsinclimit_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "Low pass & high pass filter", "Filter/Effect/Audio",
- "Low pass and high pass windowed sinc filter",
- "Thomas Vander Stichele <thomas at apestaart dot org>, "
- "Steven W. Smith, "
- "Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>, "
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
-gst_audio_wsinclimit_class_init (GstAudioWSincLimitClass * klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
- gobject_class->set_property = gst_audio_wsinclimit_set_property;
- gobject_class->get_property = gst_audio_wsinclimit_get_property;
- gobject_class->finalize = gst_audio_wsinclimit_finalize;
-
- /* FIXME: Don't use the complete possible range but restrict the upper boundary
- * so automatically generated UIs can use a slider */
- g_object_class_install_property (gobject_class, PROP_FREQUENCY,
- g_param_spec_float ("cutoff", "Cutoff",
- "Cut-off Frequency (Hz)", 0.0, 100000.0, 0.0,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_LENGTH,
- g_param_spec_int ("length", "Length",
- "Filter kernel length, will be rounded to the next odd number",
- 3, 50000, 101,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_MODE,
- g_param_spec_enum ("mode", "Mode",
- "Low pass or high pass mode", GST_TYPE_AUDIO_WSINC_LIMIT_MODE,
- MODE_LOW_PASS,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_WINDOW,
- g_param_spec_enum ("window", "Window",
- "Window function to use", GST_TYPE_AUDIO_WSINC_LIMIT_WINDOW,
- WINDOW_HAMMING,
- G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
- filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_wsinclimit_setup);
-}
-
-static void
-gst_audio_wsinclimit_init (GstAudioWSincLimit * self,
- GstAudioWSincLimitClass * g_class)
-{
- self->mode = MODE_LOW_PASS;
- self->window = WINDOW_HAMMING;
- self->kernel_length = 101;
- self->cutoff = 0.0;
-
- self->lock = g_mutex_new ();
-}
-
-static void
-gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self)
-{
- gint i = 0;
- gdouble sum = 0.0;
- gint len = 0;
- gdouble w;
- gdouble *kernel = NULL;
-
- len = self->kernel_length;
-
- if (GST_AUDIO_FILTER (self)->format.rate == 0) {
- GST_DEBUG ("rate not set yet");
- return;
- }
-
- if (GST_AUDIO_FILTER (self)->format.channels == 0) {
- GST_DEBUG ("channels not set yet");
- return;
- }
-
- /* Clamp cutoff frequency between 0 and the nyquist frequency */
- self->cutoff =
- CLAMP (self->cutoff, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2);
-
- GST_DEBUG ("gst_audio_wsinclimit_: initializing filter kernel of length %d "
- "with cutoff %.2lf Hz "
- "for mode %s",
- len, self->cutoff,
- (self->mode == MODE_LOW_PASS) ? "low-pass" : "high-pass");
-
- /* fill the kernel */
- w = 2 * M_PI * (self->cutoff / GST_AUDIO_FILTER (self)->format.rate);
-
- kernel = g_new (gdouble, len);
-
- for (i = 0; i < len; ++i) {
- if (i == len / 2)
- kernel[i] = w;
- else
- kernel[i] = sin (w * (i - len / 2)) / (i - len / 2);
- /* windowing */
- if (self->window == WINDOW_HAMMING)
- kernel[i] *= (0.54 - 0.46 * cos (2 * M_PI * i / len));
- else
- kernel[i] *= (0.42 - 0.5 * cos (2 * M_PI * i / len) +
- 0.08 * cos (4 * M_PI * i / len));
- }
-
- /* normalize for unity gain at DC */
- for (i = 0; i < len; ++i)
- sum += kernel[i];
- for (i = 0; i < len; ++i)
- kernel[i] /= sum;
-
- /* convert to highpass if specified */
- if (self->mode == MODE_HIGH_PASS) {
- for (i = 0; i < len; ++i)
- kernel[i] = -kernel[i];
- kernel[len / 2] += 1.0;
- }
-
- gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self),
- kernel, self->kernel_length, (len - 1) / 2);
-}
-
-/* GstAudioFilter vmethod implementations */
-
-/* get notified of caps and plug in the correct process function */
-static gboolean
-gst_audio_wsinclimit_setup (GstAudioFilter * base, GstRingBufferSpec * format)
-{
- GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (base);
-
- gst_audio_wsinclimit_build_kernel (self);
-
- return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
-}
-
-static void
-gst_audio_wsinclimit_finalize (GObject * object)
-{
- GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (object);
-
- g_mutex_free (self->lock);
- self->lock = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_wsinclimit_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (object);
-
- g_return_if_fail (GST_IS_AUDIO_WSINC_LIMIT (self));
-
- switch (prop_id) {
- case PROP_LENGTH:{
- gint val;
-
- g_mutex_lock (self->lock);
- val = g_value_get_int (value);
- if (val % 2 == 0)
- val++;
-
- if (val != self->kernel_length) {
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
- self->kernel_length = val;
- gst_audio_wsinclimit_build_kernel (self);
- }
- g_mutex_unlock (self->lock);
- break;
- }
- case PROP_FREQUENCY:
- g_mutex_lock (self->lock);
- self->cutoff = g_value_get_float (value);
- gst_audio_wsinclimit_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- case PROP_MODE:
- g_mutex_lock (self->lock);
- self->mode = g_value_get_enum (value);
- gst_audio_wsinclimit_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- case PROP_WINDOW:
- g_mutex_lock (self->lock);
- self->window = g_value_get_enum (value);
- gst_audio_wsinclimit_build_kernel (self);
- g_mutex_unlock (self->lock);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_audio_wsinclimit_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (object);
-
- switch (prop_id) {
- case PROP_LENGTH:
- g_value_set_int (value, self->kernel_length);
- break;
- case PROP_FREQUENCY:
- g_value_set_float (value, self->cutoff);
- break;
- case PROP_MODE:
- g_value_set_enum (value, self->mode);
- break;
- case PROP_WINDOW:
- g_value_set_enum (value, self->window);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/audiofx/audiowsinclimit.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* -*- c-basic-offset: 2 -*-
- *
- * GStreamer
- * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
- * 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
- * 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- *
- * this windowed sinc filter is taken from the freely downloadable DSP book,
- * "The Scientist and Engineer's Guide to Digital Signal Processing",
- * chapter 16
- * available at http://www.dspguide.com/
- *
- */
-
-#ifndef __GST_AUDIO_WSINC_LIMIT_H__
-#define __GST_AUDIO_WSINC_LIMIT_H__
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/gst_global.h>
-
-#include "audiofxbasefirfilter.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUDIO_WSINC_LIMIT \
- (gst_audio_wsinclimit_get_type())
-#define GST_AUDIO_WSINC_LIMIT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_WSINC_LIMIT,GstAudioWSincLimit))
-#define GST_AUDIO_WSINC_LIMIT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_WSINC_LIMIT,GstAudioWSincLimitClass))
-#define GST_IS_AUDIO_WSINC_LIMIT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_WSINC_LIMIT))
-#define GST_IS_AUDIO_WSINC_LIMIT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_WSINC_LIMIT))
-
-typedef struct _GstAudioWSincLimit GstAudioWSincLimit;
-typedef struct _GstAudioWSincLimitClass GstAudioWSincLimitClass;
-
-/**
- * GstAudioWSincLimit:
- *
- * Opaque data structure.
- */
-struct _GstAudioWSincLimit {
- GstAudioFXBaseFIRFilter parent;
-
- gint mode;
- gint window;
- gfloat cutoff;
- gint kernel_length;
-
- /* < private > */
- GMutex *lock;
-};
-
-struct _GstAudioWSincLimitClass {
- GstAudioFXBaseFIRFilterClass parent;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_audio_wsinclimit_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUDIO_WSINC_LIMIT_H__ */
--- a/gst_plugins_good/gst/audiofx/math_compat.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __MATH_COMPAT_H__
-#define __MATH_COMPAT_H__
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib.h>
-#include <math.h>
-
-#ifndef HAVE_ASINH
-static inline gdouble
-asinh (gdouble x)
-{
- return log(x + sqrt (x * x + 1));
-}
-#endif
-
-#ifndef HAVE_SINH
-static inline gdouble
-sinh (gdouble x)
-{
- return 0.5 * (exp (x) - exp (-x));
-}
-#endif
-
-#ifndef HAVE_COSH
-static inline gdouble
-cosh (gdouble x)
-{
- return 0.5 * (exp (x) + exp (-x));
-}
-#endif
-
-#endif /* __MATH_COMPAT_H__ */
--- a/gst_plugins_good/gst/auparse/gstauparse.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,726 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-auparse
- *
- * Parses .au files mostly originating from sun os based computers.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "gstauparse.h"
-#include <gst/audio/audio.h>
-
-GST_DEBUG_CATEGORY_STATIC (auparse_debug);
-#define GST_CAT_DEFAULT (auparse_debug)
-
-static const GstElementDetails gst_au_parse_details =
-GST_ELEMENT_DETAILS ("AU audio demuxer",
- "Codec/Demuxer/Audio",
- "Parse an .au file into raw audio",
- "Erik Walthinsen <omega@cse.ogi.edu>");
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-au")
- );
-
-#define GST_AU_PARSE_ALAW_PAD_TEMPLATE_CAPS \
- "audio/x-alaw, " \
- "rate = (int) [ 8000, 192000 ], " \
- "channels = (int) [ 1, 2 ]"
-
-#define GST_AU_PARSE_MULAW_PAD_TEMPLATE_CAPS \
- "audio/x-mulaw, " \
- "rate = (int) [ 8000, 192000 ], " \
- "channels = (int) [ 1, 2 ]"
-
-/* Nothing to decode those ADPCM streams for now */
-#define GST_AU_PARSE_ADPCM_PAD_TEMPLATE_CAPS \
- "audio/x-adpcm, " \
- "layout = (string) { g721, g722, g723_3, g723_5 }"
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
- GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS ";"
- GST_AU_PARSE_ALAW_PAD_TEMPLATE_CAPS ";"
- GST_AU_PARSE_MULAW_PAD_TEMPLATE_CAPS ";"
- GST_AU_PARSE_ADPCM_PAD_TEMPLATE_CAPS));
-
-
-static void gst_au_parse_dispose (GObject * object);
-static GstFlowReturn gst_au_parse_chain (GstPad * pad, GstBuffer * buf);
-static GstStateChangeReturn gst_au_parse_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_au_parse_reset (GstAuParse * auparse);
-static gboolean gst_au_parse_remove_srcpad (GstAuParse * auparse);
-static gboolean gst_au_parse_add_srcpad (GstAuParse * auparse, GstCaps * caps);
-static gboolean gst_au_parse_src_query (GstPad * pad, GstQuery * query);
-static gboolean gst_au_parse_src_event (GstPad * pad, GstEvent * event);
-static gboolean gst_au_parse_sink_event (GstPad * pad, GstEvent * event);
-
-GST_BOILERPLATE (GstAuParse, gst_au_parse, GstElement, GST_TYPE_ELEMENT);
-
-static void
-gst_au_parse_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
- gst_element_class_set_details (element_class, &gst_au_parse_details);
-
- GST_DEBUG_CATEGORY_INIT (auparse_debug, "auparse", 0, ".au parser");
-}
-
-static void
-gst_au_parse_class_init (GstAuParseClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- gobject_class->dispose = gst_au_parse_dispose;
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_au_parse_change_state);
-}
-
-static void
-gst_au_parse_init (GstAuParse * auparse, GstAuParseClass * klass)
-{
- auparse->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
- gst_pad_set_chain_function (auparse->sinkpad,
- GST_DEBUG_FUNCPTR (gst_au_parse_chain));
- gst_pad_set_event_function (auparse->sinkpad,
- GST_DEBUG_FUNCPTR (gst_au_parse_sink_event));
- gst_element_add_pad (GST_ELEMENT (auparse), auparse->sinkpad);
-
- auparse->srcpad = NULL;
- auparse->adapter = gst_adapter_new ();
- gst_au_parse_reset (auparse);
-}
-
-static void
-gst_au_parse_dispose (GObject * object)
-{
- GstAuParse *au = GST_AU_PARSE (object);
-
- if (au->adapter != NULL) {
- g_object_unref (au->adapter);
- au->adapter = NULL;
- }
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_au_parse_reset (GstAuParse * auparse)
-{
- gst_au_parse_remove_srcpad (auparse);
-
- auparse->offset = 0;
- auparse->buffer_offset = 0;
- auparse->encoding = 0;
- auparse->samplerate = 0;
- auparse->channels = 0;
-
- gst_adapter_clear (auparse->adapter);
-
- /* gst_segment_init (&auparse->segment, GST_FORMAT_TIME); */
-}
-
-static gboolean
-gst_au_parse_add_srcpad (GstAuParse * auparse, GstCaps * new_caps)
-{
- if (auparse->src_caps && gst_caps_is_equal (new_caps, auparse->src_caps)) {
- GST_LOG_OBJECT (auparse, "same caps, nothing to do");
- return TRUE;
- }
-
- gst_caps_replace (&auparse->src_caps, new_caps);
- if (auparse->srcpad != NULL) {
- GST_DEBUG_OBJECT (auparse, "Changing src pad caps to %" GST_PTR_FORMAT,
- auparse->src_caps);
- gst_pad_set_caps (auparse->srcpad, auparse->src_caps);
- }
-
- if (auparse->srcpad == NULL) {
- auparse->srcpad = gst_pad_new_from_static_template (&src_template, "src");
- g_return_val_if_fail (auparse->srcpad != NULL, FALSE);
-
-#if 0
- gst_pad_set_query_type_function (auparse->srcpad,
- GST_DEBUG_FUNCPTR (gst_au_parse_src_get_query_types));
-#endif
- gst_pad_set_query_function (auparse->srcpad,
- GST_DEBUG_FUNCPTR (gst_au_parse_src_query));
- gst_pad_set_event_function (auparse->srcpad,
- GST_DEBUG_FUNCPTR (gst_au_parse_src_event));
-
- gst_pad_use_fixed_caps (auparse->srcpad);
- gst_pad_set_active (auparse->srcpad, TRUE);
-
- if (auparse->src_caps)
- gst_pad_set_caps (auparse->srcpad, auparse->src_caps);
-
- GST_DEBUG_OBJECT (auparse, "Adding src pad with caps %" GST_PTR_FORMAT,
- auparse->src_caps);
-
- gst_object_ref (auparse->srcpad);
- if (!gst_element_add_pad (GST_ELEMENT (auparse), auparse->srcpad))
- return FALSE;
- gst_element_no_more_pads (GST_ELEMENT (auparse));
- }
-
- return TRUE;
-}
-
-static gboolean
-gst_au_parse_remove_srcpad (GstAuParse * auparse)
-{
- gboolean res = TRUE;
-
- if (auparse->srcpad != NULL) {
- GST_DEBUG_OBJECT (auparse, "Removing src pad");
- res = gst_element_remove_pad (GST_ELEMENT (auparse), auparse->srcpad);
- g_return_val_if_fail (res != FALSE, FALSE);
- gst_object_unref (auparse->srcpad);
- auparse->srcpad = NULL;
- }
-
- return res;
-}
-
-static GstFlowReturn
-gst_au_parse_parse_header (GstAuParse * auparse)
-{
- GstCaps *tempcaps;
- guint32 size;
- guint8 *head;
- gchar layout[7] = { 0, };
- gint law = 0, depth = 0, ieee = 0;
-
- head = (guint8 *) gst_adapter_peek (auparse->adapter, 24);
- g_assert (head != NULL);
-
- GST_DEBUG_OBJECT (auparse, "[%c%c%c%c]", head[0], head[1], head[2], head[3]);
-
- switch (GST_READ_UINT32_BE (head)) {
- /* normal format is big endian (au is a Sparc format) */
- case 0x2e736e64:{ /* ".snd" */
- auparse->endianness = G_BIG_ENDIAN;
- break;
- }
- /* and of course, someone had to invent a little endian
- * version. Used by DEC systems. */
- case 0x646e732e: /* dns. */
- case 0x0064732e:{ /* other source say it is "dns." */
- auparse->endianness = G_LITTLE_ENDIAN;
- break;
- }
- default:{
- goto unknown_header;
- }
- }
-
- auparse->offset = GST_READ_UINT32_BE (head + 4);
- /* Do not trust size, could be set to -1 : unknown */
- size = GST_READ_UINT32_BE (head + 8);
- auparse->encoding = GST_READ_UINT32_BE (head + 12);
- auparse->samplerate = GST_READ_UINT32_BE (head + 16);
- auparse->channels = GST_READ_UINT32_BE (head + 20);
-
- if (auparse->samplerate < 8000 || auparse->samplerate > 192000)
- goto unsupported_sample_rate;
-
- if (auparse->channels < 1 || auparse->channels > 2)
- goto unsupported_number_of_channels;
-
- GST_DEBUG_OBJECT (auparse, "offset %" G_GINT64_FORMAT ", size %u, "
- "encoding %u, frequency %u, channels %u", auparse->offset, size,
- auparse->encoding, auparse->samplerate, auparse->channels);
-
- /* Docs:
- * http://www.opengroup.org/public/pubs/external/auformat.html
- * http://astronomy.swin.edu.au/~pbourke/dataformats/au/
- * Solaris headers : /usr/include/audio/au.h
- * libsndfile : src/au.c
- *
- * Samples :
- * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/AU/Samples.html
- */
-
- switch (auparse->encoding) {
- case 1: /* 8-bit ISDN mu-law G.711 */
- law = 1;
- depth = 8;
- break;
- case 27: /* 8-bit ISDN A-law G.711 */
- law = 2;
- depth = 8;
- break;
-
- case 2: /* 8-bit linear PCM */
- depth = 8;
- break;
- case 3: /* 16-bit linear PCM */
- depth = 16;
- break;
- case 4: /* 24-bit linear PCM */
- depth = 24;
- break;
- case 5: /* 32-bit linear PCM */
- depth = 32;
- break;
-
- case 6: /* 32-bit IEEE floating point */
- ieee = 1;
- depth = 32;
- break;
- case 7: /* 64-bit IEEE floating point */
- ieee = 1;
- depth = 64;
- break;
-
- case 23: /* 4-bit CCITT G.721 ADPCM 32kbps -> modplug/libsndfile (compressed 8-bit mu-law) */
- strcpy (layout, "g721");
- break;
- case 24: /* 8-bit CCITT G.722 ADPCM -> rtp */
- strcpy (layout, "g722");
- break;
- case 25: /* 3-bit CCITT G.723.3 ADPCM 24kbps -> rtp/xine/modplug/libsndfile */
- strcpy (layout, "g723_3");
- break;
- case 26: /* 5-bit CCITT G.723.5 ADPCM 40kbps -> rtp/xine/modplug/libsndfile */
- strcpy (layout, "g723_5");
- break;
-
- case 8: /* Fragmented sample data */
- case 9: /* AU_ENCODING_NESTED */
-
- case 10: /* DSP program */
- case 11: /* DSP 8-bit fixed point */
- case 12: /* DSP 16-bit fixed point */
- case 13: /* DSP 24-bit fixed point */
- case 14: /* DSP 32-bit fixed point */
-
- case 16: /* AU_ENCODING_DISPLAY : non-audio display data */
- case 17: /* AU_ENCODING_MULAW_SQUELCH */
-
- case 18: /* 16-bit linear with emphasis */
- case 19: /* 16-bit linear compressed (NeXT) */
- case 20: /* 16-bit linear with emphasis and compression */
-
- case 21: /* Music kit DSP commands */
- case 22: /* Music kit DSP commands samples */
-
- default:
- goto unknown_format;
- }
-
- if (law) {
- tempcaps =
- gst_caps_new_simple ((law == 1) ? "audio/x-mulaw" : "audio/x-alaw",
- "rate", G_TYPE_INT, auparse->samplerate,
- "channels", G_TYPE_INT, auparse->channels, NULL);
- auparse->sample_size = auparse->channels;
- } else if (ieee) {
- tempcaps = gst_caps_new_simple ("audio/x-raw-float",
- "rate", G_TYPE_INT, auparse->samplerate,
- "channels", G_TYPE_INT, auparse->channels,
- "endianness", G_TYPE_INT, auparse->endianness,
- "width", G_TYPE_INT, depth, NULL);
- auparse->sample_size = auparse->channels * depth / 8;
- } else if (layout[0]) {
- tempcaps = gst_caps_new_simple ("audio/x-adpcm",
- "layout", G_TYPE_STRING, layout, NULL);
- auparse->sample_size = 0;
- } else {
- tempcaps = gst_caps_new_simple ("audio/x-raw-int",
- "rate", G_TYPE_INT, auparse->samplerate,
- "channels", G_TYPE_INT, auparse->channels,
- "endianness", G_TYPE_INT, auparse->endianness,
- "depth", G_TYPE_INT, depth, "width", G_TYPE_INT, depth,
- /* FIXME: signed TRUE even for 8-bit PCM? */
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- auparse->sample_size = auparse->channels * depth / 8;
- }
-
- GST_DEBUG_OBJECT (auparse, "sample_size=%d", auparse->sample_size);
-
- if (!gst_au_parse_add_srcpad (auparse, tempcaps))
- goto add_pad_failed;
-
- GST_DEBUG_OBJECT (auparse, "offset=%" G_GINT64_FORMAT, auparse->offset);
- gst_adapter_flush (auparse->adapter, auparse->offset);
-
- gst_caps_unref (tempcaps);
- return GST_FLOW_OK;
-
- /* ERRORS */
-unknown_header:
- {
- GST_ELEMENT_ERROR (auparse, STREAM, WRONG_TYPE, (NULL), (NULL));
- return GST_FLOW_ERROR;
- }
-unsupported_sample_rate:
- {
- GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
- ("Unsupported samplerate: %u", auparse->samplerate));
- return GST_FLOW_ERROR;
- }
-unsupported_number_of_channels:
- {
- GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
- ("Unsupported number of channels: %u", auparse->channels));
- return GST_FLOW_ERROR;
- }
-unknown_format:
- {
- GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
- ("Unsupported encoding: %u", auparse->encoding));
- return GST_FLOW_ERROR;
- }
-add_pad_failed:
- {
- GST_ELEMENT_ERROR (auparse, STREAM, FAILED, (NULL),
- ("Failed to add srcpad"));
- gst_caps_unref (tempcaps);
- return GST_FLOW_ERROR;
- }
-}
-
-#define AU_HEADER_SIZE 24
-
-static GstFlowReturn
-gst_au_parse_chain (GstPad * pad, GstBuffer * buf)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- GstAuParse *auparse;
- gint avail, sendnow = 0;
-
- auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
-
- GST_LOG_OBJECT (auparse, "got buffer of size %u", GST_BUFFER_SIZE (buf));
-
- gst_adapter_push (auparse->adapter, buf);
- buf = NULL;
-
- /* if we haven't seen any data yet... */
- if (auparse->srcpad == NULL) {
- if (gst_adapter_available (auparse->adapter) < AU_HEADER_SIZE) {
- GST_DEBUG_OBJECT (auparse, "need more data to parse header");
- ret = GST_FLOW_OK;
- goto out;
- }
-
- ret = gst_au_parse_parse_header (auparse);
- if (ret != GST_FLOW_OK)
- goto out;
-
- gst_pad_push_event (auparse->srcpad,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_DEFAULT,
- 0, GST_CLOCK_TIME_NONE, 0));
- }
-
- avail = gst_adapter_available (auparse->adapter);
-
- if (auparse->sample_size > 0) {
- /* Ensure we push a buffer that's a multiple of the frame size downstream */
- sendnow = avail - (avail % auparse->sample_size);
- } else {
- /* It's something non-trivial (such as ADPCM), we don't understand it, so
- * just push downstream and assume it will know what to do with it */
- sendnow = avail;
- }
-
- if (sendnow > 0) {
- GstBuffer *outbuf;
- const guint8 *data;
-
- ret = gst_pad_alloc_buffer_and_set_caps (auparse->srcpad,
- auparse->buffer_offset, sendnow, GST_PAD_CAPS (auparse->srcpad),
- &outbuf);
-
- if (ret != GST_FLOW_OK) {
- GST_DEBUG_OBJECT (auparse, "pad alloc flow: %s", gst_flow_get_name (ret));
- goto out;
- }
-
- data = gst_adapter_peek (auparse->adapter, sendnow);
- memcpy (GST_BUFFER_DATA (outbuf), data, sendnow);
- gst_adapter_flush (auparse->adapter, sendnow);
-
- auparse->buffer_offset += sendnow;
-
- ret = gst_pad_push (auparse->srcpad, outbuf);
- }
-
-out:
-
- gst_object_unref (auparse);
- return ret;
-}
-
-static gboolean
-gst_au_parse_src_convert (GstAuParse * auparse, GstFormat src_format,
- gint64 srcval, GstFormat dest_format, gint64 * destval)
-{
- gboolean ret = TRUE;
- guint samplesize, rate;
-
- if (dest_format == src_format) {
- *destval = srcval;
- return TRUE;
- }
-
- GST_OBJECT_LOCK (auparse);
- samplesize = auparse->sample_size;
- rate = auparse->samplerate;
- GST_OBJECT_UNLOCK (auparse);
-
- if (samplesize == 0 || rate == 0) {
- GST_LOG_OBJECT (auparse, "cannot convert, sample_size or rate unknown");
- return FALSE;
- }
-
- switch (src_format) {
- case GST_FORMAT_BYTES:
- srcval /= samplesize;
- /* fallthrough */
- case GST_FORMAT_DEFAULT:{
- switch (dest_format) {
- case GST_FORMAT_BYTES:
- *destval = srcval * samplesize;
- break;
- case GST_FORMAT_TIME:
- *destval = gst_util_uint64_scale_int (srcval, GST_SECOND, rate);
- break;
- default:
- ret = FALSE;
- break;
- }
- break;
- }
- case GST_FORMAT_TIME:{
- switch (dest_format) {
- case GST_FORMAT_BYTES:
- *destval =
- gst_util_uint64_scale_int (srcval, rate * samplesize, GST_SECOND);
- break;
- case GST_FORMAT_DEFAULT:
- *destval = gst_util_uint64_scale_int (srcval, rate, GST_SECOND);
- break;
- default:
- ret = FALSE;
- break;
- }
- break;
- }
- default:{
- ret = FALSE;
- break;
- }
- }
-
- if (!ret) {
- GST_DEBUG_OBJECT (auparse, "could not convert from %s to %s format",
- gst_format_get_name (src_format), gst_format_get_name (dest_format));
- }
-
- return ret;
-}
-
-static gboolean
-gst_au_parse_src_query (GstPad * pad, GstQuery * query)
-{
- GstAuParse *auparse;
- gboolean ret = FALSE;
-
- auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_DURATION:{
- GstFormat bformat = GST_FORMAT_BYTES;
- GstFormat format;
- gint64 len, val;
-
- gst_query_parse_duration (query, &format, NULL);
- if (!gst_pad_query_peer_duration (auparse->sinkpad, &bformat, &len)) {
- GST_DEBUG_OBJECT (auparse, "failed to query upstream length");
- break;
- }
- GST_OBJECT_LOCK (auparse);
- len -= auparse->offset;
- GST_OBJECT_UNLOCK (auparse);
-
- ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, len,
- format, &val);
-
- if (ret) {
- gst_query_set_duration (query, format, val);
- }
- break;
- }
- case GST_QUERY_POSITION:{
- GstFormat bformat = GST_FORMAT_BYTES;
- GstFormat format;
- gint64 pos, val;
-
- gst_query_parse_position (query, &format, NULL);
- if (!gst_pad_query_peer_position (auparse->sinkpad, &bformat, &pos)) {
- GST_DEBUG_OBJECT (auparse, "failed to query upstream position");
- break;
- }
- GST_OBJECT_LOCK (auparse);
- pos -= auparse->offset;
- GST_OBJECT_UNLOCK (auparse);
-
- ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, pos,
- format, &val);
-
- if (ret) {
- gst_query_set_position (query, format, val);
- }
- break;
- }
- default:
- ret = gst_pad_query_default (pad, query);
- break;
- }
-
- gst_object_unref (auparse);
- return ret;
-}
-
-static gboolean
-gst_au_parse_handle_seek (GstAuParse * auparse, GstEvent * event)
-{
- GstSeekType start_type, stop_type;
- GstSeekFlags flags;
- GstFormat format;
- gdouble rate;
- gint64 start, stop;
-
- gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
- &stop_type, &stop);
-
- if (format != GST_FORMAT_TIME) {
- GST_DEBUG_OBJECT (auparse, "only support seeks in TIME format");
- return FALSE;
- }
-
- /* FIXME: implement seeking */
- return FALSE;
-}
-
-static gboolean
-gst_au_parse_sink_event (GstPad * pad, GstEvent * event)
-{
- GstAuParse *auparse;
- gboolean ret;
-
- auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- default:
- ret = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (auparse);
- return ret;
-}
-
-static gboolean
-gst_au_parse_src_event (GstPad * pad, GstEvent * event)
-{
- GstAuParse *auparse;
- gboolean ret;
-
- auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEEK:
- ret = gst_au_parse_handle_seek (auparse, event);
- break;
- default:
- ret = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (auparse);
- return ret;
-}
-
-static GstStateChangeReturn
-gst_au_parse_change_state (GstElement * element, GstStateChange transition)
-{
- GstAuParse *auparse = GST_AU_PARSE (element);
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- ret = parent_class->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_au_parse_reset (auparse);
- default:
- break;
- }
-
- return ret;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "auparse", GST_RANK_SECONDARY,
- GST_TYPE_AU_PARSE)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "auparse",
- "parses au streams", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
- GST_PACKAGE_ORIGIN)
-
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
--- a/gst_plugins_good/gst/auparse/gstauparse.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_AU_PARSE_H__
-#define __GST_AU_PARSE_H__
-
-
-#include "gst/gst.h"
-#include <gst/gst_global.h>
-#include <gst/base/gstadapter.h>
-
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AU_PARSE \
- (gst_au_parse_get_type())
-#define GST_AU_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AU_PARSE,GstAuParse))
-#define GST_AU_PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AU_PARSE,GstAuParseClass))
-#define GST_IS_AU_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AU_PARSE))
-#define GST_IS_AU_PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AU_PARSE))
-
-typedef struct _GstAuParse GstAuParse;
-typedef struct _GstAuParseClass GstAuParseClass;
-
-struct _GstAuParse {
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
-
- GstCaps *src_caps;
-
- GstAdapter *adapter;
-
- /* GstSegment segment; */
-
- gint64 offset; /* where sample data starts */
- gint64 buffer_offset;
- guint sample_size;
- guint encoding;
- guint samplerate;
- guint endianness;
- guint channels;
-};
-
-struct _GstAuParseClass {
- GstElementClass parent_class;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_au_parse_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AU_PARSE_H__ */
--- a/gst_plugins_good/gst/autodetect/gstautoaudiosink.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,452 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-autoaudiosink
- * @see_also: autovideosink, alsasink, osssink
- *
- * autoaudiosink is an audio sink that automatically detects an appropriate
- * audio sink to use. It does so by scanning the registry for all elements
- * that have <quote>Sink</quote> and <quote>Audio</quote> in the class field
- * of their element information, and also have a non-zero autoplugging rank.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m audiotestsrc ! audioconvert ! audioresample ! autoaudiosink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstautoaudiosink.h"
-#include "gstautodetect.h"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_CAPS,
-};
-
-static GstStateChangeReturn
-gst_auto_audio_sink_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_auto_audio_sink_dispose (GstAutoAudioSink * sink);
-static void gst_auto_audio_sink_clear_kid (GstAutoAudioSink * sink);
-static void gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GST_BOILERPLATE (GstAutoAudioSink, gst_auto_audio_sink, GstBin, GST_TYPE_BIN);
-
-static const GstElementDetails gst_auto_audio_sink_details =
-GST_ELEMENT_DETAILS ("Auto audio sink",
- "Sink/Audio",
- "Wrapper audio sink for automatically detected audio sink",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
- "Jan Schmidt <thaytan@noraisin.net>");
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-static void
-gst_auto_audio_sink_base_init (gpointer klass)
-{
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (eklass,
- gst_static_pad_template_get (&sink_template));
-
- gst_element_class_set_details (eklass, &gst_auto_audio_sink_details);
-}
-
-static void
-gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *eklass;
-
- gobject_class = G_OBJECT_CLASS (klass);
- eklass = GST_ELEMENT_CLASS (klass);
-
- gobject_class->dispose =
- (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_auto_audio_sink_dispose);
- eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_audio_sink_change_state);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_auto_audio_sink_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_auto_audio_sink_get_property);
-
- /**
- * GstAutoAudioSink:filter-caps
- *
- * This property will filter out candidate sinks that can handle the specified
- * caps. By default only audio sinks that support raw floating point and
- * integer audio are selected.
- *
- * This property can only be set before the element goes to the READY state.
- *
- * Since: 0.10.7
- **/
- g_object_class_install_property (gobject_class, PROP_CAPS,
- g_param_spec_boxed ("filter-caps", "Filter caps",
- "Filter sink candidates using these caps.", GST_TYPE_CAPS,
- G_PARAM_READWRITE));
-}
-
-static void
-gst_auto_audio_sink_dispose (GstAutoAudioSink * sink)
-{
- gst_auto_audio_sink_clear_kid (sink);
-
- if (sink->filter_caps)
- gst_caps_unref (sink->filter_caps);
- sink->filter_caps = NULL;
-
- G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
-}
-
-static void
-gst_auto_audio_sink_clear_kid (GstAutoAudioSink * sink)
-{
- if (sink->kid) {
- gst_element_set_state (sink->kid, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (sink), sink->kid);
- sink->kid = NULL;
- }
-}
-
-/*
- * Hack to make initial linking work; ideally, this'd work even when
- * no target has been assigned to the ghostpad yet.
- */
-static void
-gst_auto_audio_sink_reset (GstAutoAudioSink * sink)
-{
- GstPad *targetpad;
-
- gst_auto_audio_sink_clear_kid (sink);
-
- /* fakesink placeholder */
- sink->kid = gst_element_factory_make ("fakesink", "tempsink");
- gst_bin_add (GST_BIN (sink), sink->kid);
-
- /* pad */
- targetpad = gst_element_get_static_pad (sink->kid, "sink");
- gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
- gst_object_unref (targetpad);
-}
-
-static GstStaticCaps raw_caps =
- GST_STATIC_CAPS ("audio/x-raw-int; audio/x-raw-float");
-
-static void
-gst_auto_audio_sink_init (GstAutoAudioSink * sink,
- GstAutoAudioSinkClass * g_class)
-{
- sink->pad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
- gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-
- gst_auto_audio_sink_reset (sink);
-
- /* set the default raw audio caps */
- sink->filter_caps = gst_static_caps_get (&raw_caps);
-
- /* mark as sink */
- GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_IS_SINK);
-}
-
-static gboolean
-gst_auto_audio_sink_factory_filter (GstPluginFeature * feature, gpointer data)
-{
- guint rank;
- const gchar *klass;
-
- /* we only care about element factories */
- if (!GST_IS_ELEMENT_FACTORY (feature))
- return FALSE;
-
- /* audio sinks */
- klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
- if (!(strstr (klass, "Sink") && strstr (klass, "Audio")))
- return FALSE;
-
- /* only select elements with autoplugging rank */
- rank = gst_plugin_feature_get_rank (feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint
-gst_auto_audio_sink_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
- if (diff != 0)
- return diff;
- return strcmp (gst_plugin_feature_get_name (f2),
- gst_plugin_feature_get_name (f1));
-}
-
-static GstElement *
-gst_auto_audio_sink_create_element_with_pretty_name (GstAutoAudioSink * sink,
- GstElementFactory * factory)
-{
- GstElement *element;
- gchar *name, *marker;
-
- marker = g_strdup (GST_PLUGIN_FEATURE (factory)->name);
- if (g_str_has_suffix (marker, "sink"))
- marker[strlen (marker) - 4] = '\0';
- if (g_str_has_prefix (marker, "gst"))
- g_memmove (marker, marker + 3, strlen (marker + 3) + 1);
- name = g_strdup_printf ("%s-actual-sink-%s", GST_OBJECT_NAME (sink), marker);
- g_free (marker);
-
- element = gst_element_factory_create (factory, name);
- g_free (name);
-
- return element;
-}
-
-static GstElement *
-gst_auto_audio_sink_find_best (GstAutoAudioSink * sink)
-{
- GList *list, *item;
- GstElement *choice = NULL;
- GstMessage *message = NULL;
- GSList *errors = NULL;
- GstBus *bus = gst_bus_new ();
- GstPad *el_pad = NULL;
- GstCaps *el_caps = NULL, *intersect = NULL;
- gboolean no_match = TRUE;
-
- list = gst_registry_feature_filter (gst_registry_get_default (),
- (GstPluginFeatureFilter) gst_auto_audio_sink_factory_filter, FALSE, sink);
- list = g_list_sort (list, (GCompareFunc) gst_auto_audio_sink_compare_ranks);
-
- /* We don't treat sound server sinks special. Our policy is that sound
- * server sinks that have a rank must not auto-spawn a daemon under any
- * circumstances, so there's nothing for us to worry about here */
- GST_LOG_OBJECT (sink, "Trying to find usable audio devices ...");
-
- for (item = list; item != NULL; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
- GstElement *el;
-
- if ((el = gst_auto_audio_sink_create_element_with_pretty_name (sink, f))) {
- GstStateChangeReturn ret;
-
- GST_DEBUG_OBJECT (sink, "Testing %s", GST_PLUGIN_FEATURE (f)->name);
-
- /* If autoaudiosink has been provided with filter caps,
- * accept only sinks that match with the filter caps */
- if (sink->filter_caps) {
- el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "sink");
- el_caps = gst_pad_get_caps (el_pad);
- gst_object_unref (el_pad);
- GST_DEBUG_OBJECT (sink,
- "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
- sink->filter_caps, el_caps);
- intersect = gst_caps_intersect (sink->filter_caps, el_caps);
- no_match = gst_caps_is_empty (intersect);
- gst_caps_unref (el_caps);
- gst_caps_unref (intersect);
-
- if (no_match) {
- GST_DEBUG_OBJECT (sink, "Incompatible caps");
- gst_object_unref (el);
- continue;
- } else {
- GST_DEBUG_OBJECT (sink, "Found compatible caps");
- }
- }
-
- gst_element_set_bus (el, bus);
- ret = gst_element_set_state (el, GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- GST_DEBUG_OBJECT (sink, "This worked!");
- choice = el;
- break;
- }
-
- /* collect all error messages */
- while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
- GST_DEBUG_OBJECT (sink, "error message %" GST_PTR_FORMAT, message);
- errors = g_slist_append (errors, message);
- }
-
- gst_element_set_state (el, GST_STATE_NULL);
- gst_object_unref (el);
- }
- }
-
- GST_DEBUG_OBJECT (sink, "done trying");
- if (!choice) {
- if (errors) {
- /* FIXME: we forward the first error for now; but later on it might make
- * sense to actually analyse them */
- gst_message_ref (GST_MESSAGE (errors->data));
- GST_DEBUG_OBJECT (sink, "reposting message %p", errors->data);
- gst_element_post_message (GST_ELEMENT (sink), GST_MESSAGE (errors->data));
- } else {
- /* send warning message to application and use a fakesink */
- GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
- ("Failed to find a usable audio sink"));
- choice = gst_element_factory_make ("fakesink", "fake-audio-sink");
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
- g_object_set (choice, "sync", TRUE, NULL);
- gst_element_set_state (choice, GST_STATE_READY);
- }
- }
- gst_object_unref (bus);
- gst_plugin_feature_list_free (list);
- g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
- g_slist_free (errors);
-
- return choice;
-}
-
-static gboolean
-gst_auto_audio_sink_detect (GstAutoAudioSink * sink)
-{
- GstElement *esink;
- GstPad *targetpad;
-
- gst_auto_audio_sink_clear_kid (sink);
-
- /* find element */
- GST_DEBUG_OBJECT (sink, "Creating new kid");
- if (!(esink = gst_auto_audio_sink_find_best (sink)))
- goto no_sink;
-
- sink->kid = esink;
- /* Ensure the child is brought up to the right state to match the parent
- * although it's currently always in READY and
- * we're always doing NULL->READY. */
- if (GST_STATE (sink->kid) < GST_STATE (sink))
- gst_element_set_state (sink->kid, GST_STATE (sink));
-
- gst_bin_add (GST_BIN (sink), esink);
-
- /* attach ghost pad */
- GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad");
- targetpad = gst_element_get_static_pad (sink->kid, "sink");
- if (!gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad))
- goto target_failed;
-
- gst_object_unref (targetpad);
- GST_DEBUG_OBJECT (sink, "done changing auto audio sink");
-
- return TRUE;
-
- /* ERRORS */
-no_sink:
- {
- GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
- ("Failed to find a supported audio sink"));
- return FALSE;
- }
-target_failed:
- {
- GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
- ("Failed to set target pad"));
- gst_object_unref (targetpad);
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_auto_audio_sink_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_auto_audio_sink_detect (sink))
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_auto_audio_sink_reset (sink);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
-
- switch (prop_id) {
- case PROP_CAPS:
- if (sink->filter_caps)
- gst_caps_unref (sink->filter_caps);
- sink->filter_caps = gst_caps_copy (gst_value_get_caps (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
-
- switch (prop_id) {
- case PROP_CAPS:{
- gst_value_set_caps (value, sink->filter_caps);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/autodetect/gstautoaudiosink.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUTO_AUDIO_SINK_H__
-#define __GST_AUTO_AUDIO_SINK_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUTO_AUDIO_SINK \
- (gst_auto_audio_sink_get_type ())
-#define GST_AUTO_AUDIO_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AUTO_AUDIO_SINK, \
- GstAutoAudioSink))
-#define GST_AUTO_AUDIO_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AUTO_AUDIO_SINK, \
- GstAutoAudioSinkClass))
-#define GST_IS_AUTO_AUDIO_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AUTO_AUDIO_SINK))
-#define GST_IS_AUTO_AUDIO_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AUTO_AUDIO_SINK))
-
-typedef struct _GstAutoAudioSink {
- GstBin parent;
-
- /* explicit pointers to stuff used */
- GstPad *pad;
- GstElement *kid;
- GstCaps *filter_caps;
-} GstAutoAudioSink;
-
-typedef struct _GstAutoAudioSinkClass {
- GstBinClass parent_class;
-} GstAutoAudioSinkClass;
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-GType gst_auto_audio_sink_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUTO_AUDIO_SINK_H__ */
--- a/gst_plugins_good/gst/autodetect/gstautoaudiosrc.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
- * (c) 2008 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-autoaudiosrc
- * @see_also: autovideosrc, alsasrc, osssrc
- *
- * autoaudiosrc is an audio source that automatically detects an appropriate
- * audio source to use. It does so by scanning the registry for all elements
- * that have <quote>Source</quote> and <quote>Audio</quote> in the class field
- * of their element information, and also have a non-zero autoplugging rank.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m autoaudiosrc ! audioconvert ! audioresample ! autoaudiosink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstautoaudiosrc.h"
-#include "gstautodetect.h"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_CAPS,
-};
-
-static GstStateChangeReturn
-gst_auto_audio_src_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_auto_audio_src_dispose (GstAutoAudioSrc * src);
-static void gst_auto_audio_src_clear_kid (GstAutoAudioSrc * src);
-static void gst_auto_audio_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_auto_audio_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GST_BOILERPLATE (GstAutoAudioSrc, gst_auto_audio_src, GstBin, GST_TYPE_BIN);
-
-static const GstElementDetails gst_auto_audio_src_details =
-GST_ELEMENT_DETAILS ("Auto audio source",
- "Source/Audio",
- "Wrapper audio source for automatically detected audio source",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
- "Jan Schmidt <thaytan@noraisin.net>\n"
- "Stefan Kost <ensonic@users.sf.net>");
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-static void
-gst_auto_audio_src_base_init (gpointer klass)
-{
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (eklass,
- gst_static_pad_template_get (&src_template));
-
- gst_element_class_set_details (eklass, &gst_auto_audio_src_details);
-}
-
-static void
-gst_auto_audio_src_class_init (GstAutoAudioSrcClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *eklass;
-
- gobject_class = G_OBJECT_CLASS (klass);
- eklass = GST_ELEMENT_CLASS (klass);
-
- gobject_class->dispose =
- (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_auto_audio_src_dispose);
- eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_audio_src_change_state);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_auto_audio_src_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_auto_audio_src_get_property);
-
- /**
- * GstAutoAudioSrc:filter-caps
- *
- * This property will filter out candidate sinks that can handle the specified
- * caps. By default only audio sinks that support raw floating point and
- * integer audio are selected.
- *
- * This property can only be set before the element goes to the READY state.
- *
- * Since: 0.10.14
- **/
- g_object_class_install_property (gobject_class, PROP_CAPS,
- g_param_spec_boxed ("filter-caps", "Filter caps",
- "Filter sink candidates using these caps.", GST_TYPE_CAPS,
- G_PARAM_READWRITE));
-}
-
-static void
-gst_auto_audio_src_dispose (GstAutoAudioSrc * sink)
-{
- gst_auto_audio_src_clear_kid (sink);
-
- if (sink->filter_caps)
- gst_caps_unref (sink->filter_caps);
- sink->filter_caps = NULL;
-
- G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
-}
-
-static void
-gst_auto_audio_src_clear_kid (GstAutoAudioSrc * sink)
-{
- if (sink->kid) {
- gst_element_set_state (sink->kid, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (sink), sink->kid);
- sink->kid = NULL;
- }
-}
-
-/*
- * Hack to make initial linking work; ideally, this'd work even when
- * no target has been assigned to the ghostpad yet.
- */
-static void
-gst_auto_audio_src_reset (GstAutoAudioSrc * src)
-{
- GstPad *targetpad;
-
- gst_auto_audio_src_clear_kid (src);
-
- /* fakesink placeholder */
- src->kid = gst_element_factory_make ("fakesrc", "tempsrc");
- gst_bin_add (GST_BIN (src), src->kid);
-
- /* pad */
- targetpad = gst_element_get_static_pad (src->kid, "src");
- gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
- gst_object_unref (targetpad);
-}
-
-static GstStaticCaps raw_caps =
- GST_STATIC_CAPS ("audio/x-raw-int; audio/x-raw-float");
-
-static void
-gst_auto_audio_src_init (GstAutoAudioSrc * src, GstAutoAudioSrcClass * g_class)
-{
- src->pad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
- gst_element_add_pad (GST_ELEMENT (src), src->pad);
-
- gst_auto_audio_src_reset (src);
-
- /* set the default raw audio caps */
- src->filter_caps = gst_static_caps_get (&raw_caps);
-
- /* mark as source */
- GST_OBJECT_FLAG_UNSET (src, GST_ELEMENT_IS_SINK);
-}
-
-static gboolean
-gst_auto_audio_src_factory_filter (GstPluginFeature * feature, gpointer data)
-{
- guint rank;
- const gchar *klass;
-
- /* we only care about element factories */
- if (!GST_IS_ELEMENT_FACTORY (feature))
- return FALSE;
-
- /* audio sinks */
- klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
- if (!(strstr (klass, "Source") && strstr (klass, "Audio")))
- return FALSE;
-
- /* only select elements with autoplugging rank */
- rank = gst_plugin_feature_get_rank (feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint
-gst_auto_audio_src_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
- if (diff != 0)
- return diff;
- return strcmp (gst_plugin_feature_get_name (f2),
- gst_plugin_feature_get_name (f1));
-}
-
-static GstElement *
-gst_auto_audio_src_create_element_with_pretty_name (GstAutoAudioSrc * src,
- GstElementFactory * factory)
-{
- GstElement *element;
- gchar *name, *marker;
-
- marker = g_strdup (GST_PLUGIN_FEATURE (factory)->name);
- if (g_str_has_suffix (marker, "src"))
- marker[strlen (marker) - 4] = '\0';
- if (g_str_has_prefix (marker, "gst"))
- g_memmove (marker, marker + 3, strlen (marker + 3) + 1);
- name = g_strdup_printf ("%s-actual-src-%s", GST_OBJECT_NAME (src), marker);
- g_free (marker);
-
- element = gst_element_factory_create (factory, name);
- g_free (name);
-
- return element;
-}
-
-static GstElement *
-gst_auto_audio_src_find_best (GstAutoAudioSrc * src)
-{
- GList *list, *item;
- GstElement *choice = NULL;
- GstMessage *message = NULL;
- GSList *errors = NULL;
- GstBus *bus = gst_bus_new ();
- GstPad *el_pad = NULL;
- GstCaps *el_caps = NULL, *intersect = NULL;
- gboolean no_match = TRUE;
-
- list = gst_registry_feature_filter (gst_registry_get_default (),
- (GstPluginFeatureFilter) gst_auto_audio_src_factory_filter, FALSE, src);
- list = g_list_sort (list, (GCompareFunc) gst_auto_audio_src_compare_ranks);
-
- /* We don't treat sound server sources special. Our policy is that sound
- * server sources that have a rank must not auto-spawn a daemon under any
- * circumstances, so there's nothing for us to worry about here */
- GST_LOG_OBJECT (src, "Trying to find usable audio devices ...");
-
- for (item = list; item != NULL; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
- GstElement *el;
-
- if ((el = gst_auto_audio_src_create_element_with_pretty_name (src, f))) {
- GstStateChangeReturn ret;
-
- GST_DEBUG_OBJECT (src, "Testing %s", GST_PLUGIN_FEATURE (f)->name);
-
- /* If autoAudioSrc has been provided with filter caps,
- * accept only sources that match with the filter caps */
- if (src->filter_caps) {
- el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "src");
- el_caps = gst_pad_get_caps (el_pad);
- gst_object_unref (el_pad);
- GST_DEBUG_OBJECT (src,
- "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
- src->filter_caps, el_caps);
- intersect = gst_caps_intersect (src->filter_caps, el_caps);
- no_match = gst_caps_is_empty (intersect);
- gst_caps_unref (el_caps);
- gst_caps_unref (intersect);
-
- if (no_match) {
- GST_DEBUG_OBJECT (src, "Incompatible caps");
- gst_object_unref (el);
- continue;
- } else {
- GST_DEBUG_OBJECT (src, "Found compatible caps");
- }
- }
-
- gst_element_set_bus (el, bus);
- ret = gst_element_set_state (el, GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- GST_DEBUG_OBJECT (src, "This worked!");
- choice = el;
- break;
- }
-
- /* collect all error messages */
- while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
- GST_DEBUG_OBJECT (src, "error message %" GST_PTR_FORMAT, message);
- errors = g_slist_append (errors, message);
- }
-
- gst_element_set_state (el, GST_STATE_NULL);
- gst_object_unref (el);
- }
- }
-
- GST_DEBUG_OBJECT (src, "done trying");
- if (!choice) {
- if (errors) {
- /* FIXME: we forward the first error for now; but later on it might make
- * sense to actually analyse them */
- gst_message_ref (GST_MESSAGE (errors->data));
- GST_DEBUG_OBJECT (src, "reposting message %p", errors->data);
- gst_element_post_message (GST_ELEMENT (src), GST_MESSAGE (errors->data));
- } else {
- /* send warning message to application and use a fakesrc */
- GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL),
- ("Failed to find a usable audio source"));
- choice = gst_element_factory_make ("fakesrc", "fake-audio-src");
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
- g_object_set (choice, "sync", TRUE, NULL);
- gst_element_set_state (choice, GST_STATE_READY);
- }
- }
- gst_object_unref (bus);
- gst_plugin_feature_list_free (list);
- g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
- g_slist_free (errors);
-
- return choice;
-}
-
-static gboolean
-gst_auto_audio_src_detect (GstAutoAudioSrc * src)
-{
- GstElement *esrc;
- GstPad *targetpad;
-
- gst_auto_audio_src_clear_kid (src);
-
- /* find element */
- GST_DEBUG_OBJECT (src, "Creating new kid");
- if (!(esrc = gst_auto_audio_src_find_best (src)))
- goto no_src;
-
- src->kid = esrc;
- /* Ensure the child is brought up to the right state to match the parent
- * although it's currently always in READY and
- * we're always doing NULL->READY. */
- if (GST_STATE (src->kid) < GST_STATE (src))
- gst_element_set_state (src->kid, GST_STATE (src));
-
- gst_bin_add (GST_BIN (src), esrc);
-
- /* attach ghost pad */
- GST_DEBUG_OBJECT (src, "Re-assigning ghostpad");
- targetpad = gst_element_get_static_pad (src->kid, "src");
- if (!gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad))
- goto target_failed;
-
- gst_object_unref (targetpad);
- GST_DEBUG_OBJECT (src, "done changing auto audio source");
-
- return TRUE;
-
- /* ERRORS */
-no_src:
- {
- GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
- ("Failed to find a supported audio source"));
- return FALSE;
- }
-target_failed:
- {
- GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
- ("Failed to set target pad"));
- gst_object_unref (targetpad);
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_auto_audio_src_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstAutoAudioSrc *src = GST_AUTO_AUDIO_SRC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_auto_audio_src_detect (src))
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_auto_audio_src_reset (src);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_auto_audio_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAutoAudioSrc *src = GST_AUTO_AUDIO_SRC (object);
-
- switch (prop_id) {
- case PROP_CAPS:
- if (src->filter_caps)
- gst_caps_unref (src->filter_caps);
- src->filter_caps = gst_caps_copy (gst_value_get_caps (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_auto_audio_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAutoAudioSrc *src = GST_AUTO_AUDIO_SRC (object);
-
- switch (prop_id) {
- case PROP_CAPS:{
- gst_value_set_caps (value, src->filter_caps);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/autodetect/gstautoaudiosrc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2008 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUTO_AUDIO_SRC_H__
-#define __GST_AUTO_AUDIO_SRC_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUTO_AUDIO_SRC \
- (gst_auto_audio_src_get_type ())
-#define GST_AUTO_AUDIO_SRC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AUTO_AUDIO_SRC, \
- GstAutoAudioSrc))
-#define GST_AUTO_AUDIO_SRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AUTO_AUDIO_SRC, \
- GstAutoAudioSrcClass))
-#define GST_IS_AUTO_AUDIO_SRC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AUTO_AUDIO_SRC))
-#define GST_IS_AUTO_AUDIO_SRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AUTO_AUDIO_SRC))
-
-typedef struct _GstAutoAudioSrc {
- GstBin parent;
-
- /* explicit pointers to stuff used */
- GstPad *pad;
- GstElement *kid;
- GstCaps *filter_caps;
-} GstAutoAudioSrc;
-
-typedef struct _GstAutoAudioSrcClass {
- GstBinClass parent_class;
-} GstAutoAudioSrcClass;
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_auto_audio_src_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUTO_AUDIO_SRC_H__ */
--- a/gst_plugins_good/gst/autodetect/gstautodetect.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-
-#include "gstautodetect.h"
-#include "gstautoaudiosink.h"
-#include "gstautoaudiosrc.h"
-#include "gstautovideosink.h"
-#include "gstautovideosrc.h"
-
-GST_DEBUG_CATEGORY (autodetect_debug);
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- GST_DEBUG_CATEGORY_INIT (autodetect_debug, "autodetect", 0,
- "Autodetection audio/video output wrapper elements");
-
- return gst_element_register (plugin, "autovideosink",
- GST_RANK_NONE, GST_TYPE_AUTO_VIDEO_SINK) &&
- gst_element_register (plugin, "autovideosrc",
- GST_RANK_NONE, GST_TYPE_AUTO_VIDEO_SRC) &&
- gst_element_register (plugin, "autoaudiosink",
- GST_RANK_NONE, GST_TYPE_AUTO_AUDIO_SINK) &&
- gst_element_register (plugin, "autoaudiosrc",
- GST_RANK_NONE, GST_TYPE_AUTO_AUDIO_SRC);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "autodetect",
- "Plugin contains auto-detection plugins for video/audio in- and outputs",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-#ifdef __SYMBIAN32__
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-#endif
\ No newline at end of file
--- a/gst_plugins_good/gst/autodetect/gstautodetect.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUTO_DETECT_H__
-#define __GST_AUTO_DETECT_H__
-
-GST_DEBUG_CATEGORY_EXTERN (autodetect_debug);
-#define GST_CAT_DEFAULT autodetect_debug
-
-#endif /* __GST_AUTO_DETECT_H__ */
--- a/gst_plugins_good/gst/autodetect/gstautovideosink.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,441 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-autovideosink
- * @see_also: autoaudiosink, ximagesink, xvimagesink, sdlvideosink
- *
- * autovideosink is a video sink that automatically detects an appropriate
- * video sink to use. It does so by scanning the registry for all elements
- * that have <quote>Sink</quote> and <quote>Video</quote> in the class field
- * of their element information, and also have a non-zero autoplugging rank.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m videotestsrc ! autovideosink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstautovideosink.h"
-#include "gstautodetect.h"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_CAPS,
-};
-
-static GstStateChangeReturn
-gst_auto_video_sink_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_auto_video_sink_dispose (GstAutoVideoSink * sink);
-static void gst_auto_video_sink_clear_kid (GstAutoVideoSink * sink);
-
-static void gst_auto_video_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_auto_video_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GST_BOILERPLATE (GstAutoVideoSink, gst_auto_video_sink, GstBin, GST_TYPE_BIN);
-
-static const GstElementDetails gst_auto_video_sink_details =
-GST_ELEMENT_DETAILS ("Auto video sink",
- "Sink/Video",
- "Wrapper video sink for automatically detected video sink",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
- "Jan Schmidt <thaytan@noraisin.net>");
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-static void
-gst_auto_video_sink_base_init (gpointer klass)
-{
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (eklass,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_set_details (eklass, &gst_auto_video_sink_details);
-}
-
-static void
-gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose =
- (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_auto_video_sink_dispose);
- eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_video_sink_change_state);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_auto_video_sink_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_auto_video_sink_get_property);
-
- /**
- * GstAutoVideoSink:filter-caps
- *
- * This property will filter out candidate sinks that can handle the specified
- * caps. By default only video sinks that support raw rgb and yuv video
- * are selected.
- *
- * This property can only be set before the element goes to the READY state.
- *
- * Since: 0.10.7
- **/
- g_object_class_install_property (gobject_class, PROP_CAPS,
- g_param_spec_boxed ("filter-caps", "Filter caps",
- "Filter sink candidates using these caps.", GST_TYPE_CAPS,
- G_PARAM_READWRITE));
-}
-
-static void
-gst_auto_video_sink_dispose (GstAutoVideoSink * sink)
-{
- gst_auto_video_sink_clear_kid (sink);
-
- if (sink->filter_caps)
- gst_caps_unref (sink->filter_caps);
- sink->filter_caps = NULL;
-
- G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
-}
-
-static void
-gst_auto_video_sink_clear_kid (GstAutoVideoSink * sink)
-{
- if (sink->kid) {
- gst_element_set_state (sink->kid, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (sink), sink->kid);
- sink->kid = NULL;
- }
-}
-
-/*
- * Hack to make initial linking work; ideally, this'd work even when
- * no target has been assigned to the ghostpad yet.
- */
-
-static void
-gst_auto_video_sink_reset (GstAutoVideoSink * sink)
-{
- GstPad *targetpad;
-
- /* Remove any existing element */
- gst_auto_video_sink_clear_kid (sink);
-
- /* fakesink placeholder */
- sink->kid = gst_element_factory_make ("fakesink", "tempsink");
- gst_bin_add (GST_BIN (sink), sink->kid);
-
- /* pad, setting this target should always work */
- targetpad = gst_element_get_static_pad (sink->kid, "sink");
- gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
- gst_object_unref (targetpad);
-}
-
-static GstStaticCaps raw_caps =
- GST_STATIC_CAPS ("video/x-raw-yuv; video/x-raw-rgb");
-
-static void
-gst_auto_video_sink_init (GstAutoVideoSink * sink,
- GstAutoVideoSinkClass * g_class)
-{
- sink->pad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
- gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-
- gst_auto_video_sink_reset (sink);
-
- /* set the default raw video caps */
- sink->filter_caps = gst_static_caps_get (&raw_caps);
-
- /* mark as sink */
- GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_IS_SINK);
-}
-
-static gboolean
-gst_auto_video_sink_factory_filter (GstPluginFeature * feature, gpointer data)
-{
- guint rank;
- const gchar *klass;
-
- /* we only care about element factories */
- if (!GST_IS_ELEMENT_FACTORY (feature))
- return FALSE;
-
- /* video sinks */
- klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
- if (!(strstr (klass, "Sink") && strstr (klass, "Video")))
- return FALSE;
-
- /* only select elements with autoplugging rank */
- rank = gst_plugin_feature_get_rank (feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint
-gst_auto_video_sink_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
- if (diff != 0)
- return diff;
- return strcmp (gst_plugin_feature_get_name (f2),
- gst_plugin_feature_get_name (f1));
-}
-
-static GstElement *
-gst_auto_video_sink_create_element_with_pretty_name (GstAutoVideoSink * sink,
- GstElementFactory * factory)
-{
- GstElement *element;
- gchar *name, *marker;
-
- marker = g_strdup (GST_PLUGIN_FEATURE (factory)->name);
- if (g_str_has_suffix (marker, "sink"))
- marker[strlen (marker) - 4] = '\0';
- if (g_str_has_prefix (marker, "gst"))
- g_memmove (marker, marker + 3, strlen (marker + 3) + 1);
- name = g_strdup_printf ("%s-actual-sink-%s", GST_OBJECT_NAME (sink), marker);
- g_free (marker);
-
- element = gst_element_factory_create (factory, name);
- g_free (name);
-
- return element;
-}
-
-static GstElement *
-gst_auto_video_sink_find_best (GstAutoVideoSink * sink)
-{
- GList *list, *item;
- GstElement *choice = NULL;
- GstMessage *message = NULL;
- GSList *errors = NULL;
- GstBus *bus = gst_bus_new ();
- GstPad *el_pad = NULL;
- GstCaps *el_caps = NULL, *intersect = NULL;
- gboolean no_match = TRUE;
-
- list = gst_registry_feature_filter (gst_registry_get_default (),
- (GstPluginFeatureFilter) gst_auto_video_sink_factory_filter, FALSE, sink);
- list = g_list_sort (list, (GCompareFunc) gst_auto_video_sink_compare_ranks);
-
- GST_LOG_OBJECT (sink, "Trying to find usable video devices ...");
-
- for (item = list; item != NULL; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
- GstElement *el;
-
- if ((el = gst_auto_video_sink_create_element_with_pretty_name (sink, f))) {
- GstStateChangeReturn ret;
-
- GST_DEBUG_OBJECT (sink, "Testing %s", GST_PLUGIN_FEATURE (f)->name);
-
- /* If autovideosink has been provided with filter caps,
- * accept only sinks that match with the filter caps */
- if (sink->filter_caps) {
- el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "sink");
- el_caps = gst_pad_get_caps (el_pad);
- gst_object_unref (el_pad);
- GST_DEBUG_OBJECT (sink,
- "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
- sink->filter_caps, el_caps);
- intersect = gst_caps_intersect (sink->filter_caps, el_caps);
- no_match = gst_caps_is_empty (intersect);
- gst_caps_unref (el_caps);
- gst_caps_unref (intersect);
-
- if (no_match) {
- GST_DEBUG_OBJECT (sink, "Incompatible caps");
- gst_object_unref (el);
- continue;
- } else {
- GST_DEBUG_OBJECT (sink, "Found compatible caps");
- }
- }
-
- gst_element_set_bus (el, bus);
- ret = gst_element_set_state (el, GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- GST_DEBUG_OBJECT (sink, "This worked!");
- choice = el;
- break;
- }
-
- /* collect all error messages */
- while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
- GST_DEBUG_OBJECT (sink, "error message %" GST_PTR_FORMAT, message);
- errors = g_slist_append (errors, message);
- }
-
- gst_element_set_state (el, GST_STATE_NULL);
- gst_object_unref (el);
- }
- }
-
- GST_DEBUG_OBJECT (sink, "done trying");
- if (!choice) {
- if (errors) {
- /* FIXME: we forward the first error for now; but later on it might make
- * sense to actually analyse them */
- gst_message_ref (GST_MESSAGE (errors->data));
- GST_DEBUG_OBJECT (sink, "reposting message %p", errors->data);
- gst_element_post_message (GST_ELEMENT (sink), GST_MESSAGE (errors->data));
- } else {
- /* send warning message to application and use a fakesink */
- GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
- ("Failed to find a usable video sink"));
- choice = gst_element_factory_make ("fakesink", "fake-video-sink");
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
- g_object_set (choice, "sync", TRUE, NULL);
- gst_element_set_state (choice, GST_STATE_READY);
- }
- }
- gst_object_unref (bus);
- gst_plugin_feature_list_free (list);
- g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
- g_slist_free (errors);
-
- return choice;
-}
-
-static gboolean
-gst_auto_video_sink_detect (GstAutoVideoSink * sink)
-{
- GstElement *esink;
- GstPad *targetpad;
-
- gst_auto_video_sink_clear_kid (sink);
-
- /* find element */
- GST_DEBUG_OBJECT (sink, "Creating new kid");
- if (!(esink = gst_auto_video_sink_find_best (sink)))
- goto no_sink;
-
- sink->kid = esink;
- gst_bin_add (GST_BIN (sink), esink);
-
- /* attach ghost pad */
- GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad");
- targetpad = gst_element_get_static_pad (sink->kid, "sink");
- if (!gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad))
- goto target_failed;
-
- gst_object_unref (targetpad);
- GST_DEBUG_OBJECT (sink, "done changing auto video sink");
-
- return TRUE;
-
- /* ERRORS */
-no_sink:
- {
- GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
- ("Failed to find a supported video sink"));
- return FALSE;
- }
-target_failed:
- {
- GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
- ("Failed to set target pad"));
- gst_object_unref (targetpad);
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_auto_video_sink_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_auto_video_sink_detect (sink))
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_auto_video_sink_reset (sink);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_auto_video_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (object);
-
- switch (prop_id) {
- case PROP_CAPS:
- if (sink->filter_caps)
- gst_caps_unref (sink->filter_caps);
- sink->filter_caps = gst_caps_copy (gst_value_get_caps (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_auto_video_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (object);
-
- switch (prop_id) {
- case PROP_CAPS:{
- gst_value_set_caps (value, sink->filter_caps);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/autodetect/gstautovideosink.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUTO_VIDEO_SINK_H__
-#define __GST_AUTO_VIDEO_SINK_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUTO_VIDEO_SINK \
- (gst_auto_video_sink_get_type ())
-#define GST_AUTO_VIDEO_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AUTO_VIDEO_SINK, \
- GstAutoVideoSink))
-#define GST_AUTO_VIDEO_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AUTO_VIDEO_SINK, \
- GstAutoVideoSinkClass))
-#define GST_IS_AUTO_VIDEO_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AUTO_VIDEO_SINK))
-#define GST_IS_AUTO_VIDEO_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AUTO_VIDEO_SINK))
-
-typedef struct _GstAutoVideoSink {
- GstBin parent;
-
- /* explicit pointers to stuff used */
- GstPad *pad;
- GstElement *kid;
- GstCaps *filter_caps;
-} GstAutoVideoSink;
-
-typedef struct _GstAutoVideoSinkClass {
- GstBinClass parent_class;
-} GstAutoVideoSinkClass;
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_auto_video_sink_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUTO_VIDEO_SINK_H__ */
--- a/gst_plugins_good/gst/autodetect/gstautovideosrc.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,442 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
- * (c) 2008 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-autovideosrc
- * @see_also: autoaudiosrc, v4l2src, v4lsrc
- *
- * autovideosrc is a video src that automatically detects an appropriate
- * video source to use. It does so by scanning the registry for all elements
- * that have <quote>Source</quote> and <quote>Video</quote> in the class field
- * of their element information, and also have a non-zero autoplugging rank.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m autovideosrc ! xvimagesink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstautovideosrc.h"
-#include "gstautodetect.h"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_CAPS,
-};
-
-static GstStateChangeReturn
-gst_auto_video_src_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_auto_video_src_dispose (GstAutoVideoSrc * src);
-static void gst_auto_video_src_clear_kid (GstAutoVideoSrc * src);
-
-static void gst_auto_video_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_auto_video_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GST_BOILERPLATE (GstAutoVideoSrc, gst_auto_video_src, GstBin, GST_TYPE_BIN);
-
-static const GstElementDetails gst_auto_video_src_details =
-GST_ELEMENT_DETAILS ("Auto video source",
- "Source/Video",
- "Wrapper video source for automatically detected video source",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
- "Jan Schmidt <thaytan@noraisin.net>\n"
- "Stefan Kost <ensonic@users.sf.net>");
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-static void
-gst_auto_video_src_base_init (gpointer klass)
-{
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (eklass,
- gst_static_pad_template_get (&src_template));
- gst_element_class_set_details (eklass, &gst_auto_video_src_details);
-}
-
-static void
-gst_auto_video_src_class_init (GstAutoVideoSrcClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose =
- (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_auto_video_src_dispose);
- eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_video_src_change_state);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_auto_video_src_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_auto_video_src_get_property);
-
- /**
- * GstAutoVideoSrc:filter-caps
- *
- * This property will filter out candidate sources that can handle the specified
- * caps. By default only video sources that support raw rgb and yuv video
- * are selected.
- *
- * This property can only be set before the element goes to the READY state.
- *
- * Since: 0.10.14
- **/
- g_object_class_install_property (gobject_class, PROP_CAPS,
- g_param_spec_boxed ("filter-caps", "Filter caps",
- "Filter src candidates using these caps.", GST_TYPE_CAPS,
- G_PARAM_READWRITE));
-}
-
-static void
-gst_auto_video_src_dispose (GstAutoVideoSrc * src)
-{
- gst_auto_video_src_clear_kid (src);
-
- if (src->filter_caps)
- gst_caps_unref (src->filter_caps);
- src->filter_caps = NULL;
-
- G_OBJECT_CLASS (parent_class)->dispose ((GObject *) src);
-}
-
-static void
-gst_auto_video_src_clear_kid (GstAutoVideoSrc * src)
-{
- if (src->kid) {
- gst_element_set_state (src->kid, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (src), src->kid);
- src->kid = NULL;
- }
-}
-
-/*
- * Hack to make initial linking work; ideally, this'd work even when
- * no target has been assigned to the ghostpad yet.
- */
-
-static void
-gst_auto_video_src_reset (GstAutoVideoSrc * src)
-{
- GstPad *targetpad;
-
- /* Remove any existing element */
- gst_auto_video_src_clear_kid (src);
-
- /* fakesrc placeholder */
- src->kid = gst_element_factory_make ("fakesrc", "tempsrc");
- gst_bin_add (GST_BIN (src), src->kid);
-
- /* pad */
- targetpad = gst_element_get_static_pad (src->kid, "src");
- gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
- gst_object_unref (targetpad);
-}
-
-static GstStaticCaps raw_caps =
- GST_STATIC_CAPS ("video/x-raw-yuv; video/x-raw-rgb");
-
-static void
-gst_auto_video_src_init (GstAutoVideoSrc * src, GstAutoVideoSrcClass * g_class)
-{
- src->pad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
- gst_element_add_pad (GST_ELEMENT (src), src->pad);
-
- gst_auto_video_src_reset (src);
-
- /* set the default raw video caps */
- src->filter_caps = gst_static_caps_get (&raw_caps);
-
- /* mark as source */
- GST_OBJECT_FLAG_UNSET (src, GST_ELEMENT_IS_SINK);
-}
-
-static gboolean
-gst_auto_video_src_factory_filter (GstPluginFeature * feature, gpointer data)
-{
- guint rank;
- const gchar *klass;
-
- /* we only care about element factories */
- if (!GST_IS_ELEMENT_FACTORY (feature))
- return FALSE;
-
- /* video sources */
- klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
- if (!(strstr (klass, "Source") && strstr (klass, "Video")))
- return FALSE;
-
- /* only select elements with autoplugging rank */
- rank = gst_plugin_feature_get_rank (feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint
-gst_auto_video_src_compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
- if (diff != 0)
- return diff;
- return strcmp (gst_plugin_feature_get_name (f2),
- gst_plugin_feature_get_name (f1));
-}
-
-static GstElement *
-gst_auto_video_src_create_element_with_pretty_name (GstAutoVideoSrc * src,
- GstElementFactory * factory)
-{
- GstElement *element;
- gchar *name, *marker;
-
- marker = g_strdup (GST_PLUGIN_FEATURE (factory)->name);
- if (g_str_has_suffix (marker, "src"))
- marker[strlen (marker) - 4] = '\0';
- if (g_str_has_prefix (marker, "gst"))
- g_memmove (marker, marker + 3, strlen (marker + 3) + 1);
- name = g_strdup_printf ("%s-actual-src-%s", GST_OBJECT_NAME (src), marker);
- g_free (marker);
-
- element = gst_element_factory_create (factory, name);
- g_free (name);
-
- return element;
-}
-
-static GstElement *
-gst_auto_video_src_find_best (GstAutoVideoSrc * src)
-{
- GList *list, *item;
- GstElement *choice = NULL;
- GstMessage *message = NULL;
- GSList *errors = NULL;
- GstBus *bus = gst_bus_new ();
- GstPad *el_pad = NULL;
- GstCaps *el_caps = NULL, *intersect = NULL;
- gboolean no_match = TRUE;
-
- list = gst_registry_feature_filter (gst_registry_get_default (),
- (GstPluginFeatureFilter) gst_auto_video_src_factory_filter, FALSE, src);
- list = g_list_sort (list, (GCompareFunc) gst_auto_video_src_compare_ranks);
-
- GST_LOG_OBJECT (src, "Trying to find usable video devices ...");
-
- for (item = list; item != NULL; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
- GstElement *el;
-
- if ((el = gst_auto_video_src_create_element_with_pretty_name (src, f))) {
- GstStateChangeReturn ret;
-
- GST_DEBUG_OBJECT (src, "Testing %s", GST_PLUGIN_FEATURE (f)->name);
-
- /* If AutoVideoSrc has been provided with filter caps,
- * accept only sources that match with the filter caps */
- if (src->filter_caps) {
- el_pad = gst_element_get_static_pad (GST_ELEMENT (el), "src");
- el_caps = gst_pad_get_caps (el_pad);
- gst_object_unref (el_pad);
- GST_DEBUG_OBJECT (src,
- "Checking caps: %" GST_PTR_FORMAT " vs. %" GST_PTR_FORMAT,
- src->filter_caps, el_caps);
- intersect = gst_caps_intersect (src->filter_caps, el_caps);
- no_match = gst_caps_is_empty (intersect);
- gst_caps_unref (el_caps);
- gst_caps_unref (intersect);
-
- if (no_match) {
- GST_DEBUG_OBJECT (src, "Incompatible caps");
- gst_object_unref (el);
- continue;
- } else {
- GST_DEBUG_OBJECT (src, "Found compatible caps");
- }
- }
-
- gst_element_set_bus (el, bus);
- ret = gst_element_set_state (el, GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- GST_DEBUG_OBJECT (src, "This worked!");
- choice = el;
- break;
- }
-
- /* collect all error messages */
- while ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR))) {
- GST_DEBUG_OBJECT (src, "error message %" GST_PTR_FORMAT, message);
- errors = g_slist_append (errors, message);
- }
-
- gst_element_set_state (el, GST_STATE_NULL);
- gst_object_unref (el);
- }
- }
-
- GST_DEBUG_OBJECT (src, "done trying");
- if (!choice) {
- if (errors) {
- /* FIXME: we forward the first error for now; but later on it might make
- * sense to actually analyse them */
- gst_message_ref (GST_MESSAGE (errors->data));
- GST_DEBUG_OBJECT (src, "reposting message %p", errors->data);
- gst_element_post_message (GST_ELEMENT (src), GST_MESSAGE (errors->data));
- } else {
- /* send warning message to application and use a fakesrc */
- GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL),
- ("Failed to find a usable video source"));
- choice = gst_element_factory_make ("fakesrc", "fake-video-src");
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (choice), "sync"))
- g_object_set (choice, "sync", TRUE, NULL);
- gst_element_set_state (choice, GST_STATE_READY);
- }
- }
- gst_object_unref (bus);
- gst_plugin_feature_list_free (list);
- g_slist_foreach (errors, (GFunc) gst_mini_object_unref, NULL);
- g_slist_free (errors);
-
- return choice;
-}
-
-static gboolean
-gst_auto_video_src_detect (GstAutoVideoSrc * src)
-{
- GstElement *esrc;
- GstPad *targetpad;
-
- gst_auto_video_src_clear_kid (src);
-
- /* find element */
- GST_DEBUG_OBJECT (src, "Creating new kid");
- if (!(esrc = gst_auto_video_src_find_best (src)))
- goto no_src;
-
- src->kid = esrc;
- gst_bin_add (GST_BIN (src), esrc);
-
- /* attach ghost pad */
- GST_DEBUG_OBJECT (src, "Re-assigning ghostpad");
- targetpad = gst_element_get_static_pad (src->kid, "src");
- if (!gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad))
- goto target_failed;
-
- gst_object_unref (targetpad);
- GST_DEBUG_OBJECT (src, "done changing auto video source");
-
- return TRUE;
-
- /* ERRORS */
-no_src:
- {
- GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
- ("Failed to find a supported video source"));
- return FALSE;
- }
-target_failed:
- {
- GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
- ("Failed to set target pad"));
- gst_object_unref (targetpad);
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_auto_video_src_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstAutoVideoSrc *src = GST_AUTO_VIDEO_SRC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_auto_video_src_detect (src))
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_auto_video_src_reset (src);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_auto_video_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstAutoVideoSrc *src = GST_AUTO_VIDEO_SRC (object);
-
- switch (prop_id) {
- case PROP_CAPS:
- if (src->filter_caps)
- gst_caps_unref (src->filter_caps);
- src->filter_caps = gst_caps_copy (gst_value_get_caps (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_auto_video_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstAutoVideoSrc *src = GST_AUTO_VIDEO_SRC (object);
-
- switch (prop_id) {
- case PROP_CAPS:{
- gst_value_set_caps (value, src->filter_caps);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
--- a/gst_plugins_good/gst/autodetect/gstautovideosrc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* GStreamer
- * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * (c) 2008 Stefan Kost <ensonic@users.sf.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AUTO_VIDEO_SRC_H__
-#define __GST_AUTO_VIDEO_SRC_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AUTO_VIDEO_SRC \
- (gst_auto_video_src_get_type ())
-#define GST_AUTO_VIDEO_SRC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AUTO_VIDEO_SRC, \
- GstAutoVideoSrc))
-#define GST_AUTO_VIDEO_SRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AUTO_VIDEO_SRC, \
- GstAutoVideoSrcClass))
-#define GST_IS_AUTO_VIDEO_SRC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AUTO_VIDEO_SRC))
-#define GST_IS_AUTO_VIDEO_SRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AUTO_VIDEO_SRC))
-
-typedef struct _GstAutoVideoSrc {
- GstBin parent;
-
- /* explicit pointers to stuff used */
- GstPad *pad;
- GstElement *kid;
- GstCaps *filter_caps;
-} GstAutoVideoSrc;
-
-typedef struct _GstAutoVideoSrcClass {
- GstBinClass parent_class;
-} GstAutoVideoSrcClass;
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_auto_video_src_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AUTO_VIDEO_SRC_H__ */
--- a/gst_plugins_good/gst/avi/README Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-The avi decoder plugins
------------------------
-
-The avi decoder consists of a set of gstreamer plugins:
-
- - demuxer (avidemux)
- - avi to gstreamer type converter (avitypes)
- - windows dlls wrappers.
-
-the avidecoder element uses the above plugins to perform the avi
-decoding. It is constructed as a custom bin which initially only has
-the demuxer element in it. The demuxer has a set of padtemplates for
-raw audio and video.
-
- (------------------------------------)
- ! avidecoder !
- ! (video/raw)...
- ! (----------) !
- ! ! demuxer (video/x-msvideo, auds)..
- ! ! ! !
- ! -src ! !
- ! / ! (video/x-msvideo, vids)..
- - src ! ! !
- ! (----------) (audio/raw)...
- ! !
- (------------------------------------)
-
-the demuxer has a set of padtemplates for the raw avi header properties.
-
-The avi decoder will act on the new_pad signal of the demuxer element
-and will attach an avitype plugin to the new pad. Caps negotiation will
-convert the raw avi caps to the gstreamer caps. If the src pad of the
-avitypes plugin are compatible with the avidecoder padtemplate, the
-avitype pad is ghosted to the avidecoder bin, this is the case where no
-codec is needed (for raw PCM samples, for example).
-
-When the avitypes caps are not compatible with one of the avidecoder
-templates, a static autoplugger is used the find an element to connect
-the demuxers pad to the decoders padtemplate.
-
-When no element could be found, an windec plugin is attached to the
-demuxers pad and the avitypes plugin is removed from the decoder.
-
-
-example:
---------
-
- An avidecoder that has a video pad (decoded with windows dlls) and an
- audio pad (raw PCM).
-
- (----------------------------------------------------------------)
- ! avidecoder (--------) (------) !
- ! !avitypes! !windec! /-- (video/raw)
- ! (----------) /-sink src--sink src ----- !
- ! !demuxer (video/x-msvideo, ! ! ! !
- ! ! ! auds).. (--------) (------) !
- ! -sink ! (--------) !
- ! / ! (video/x-..,!avitypes! !
- -sink ! ! vids).. ! ! !
- ! (----------) \-sink src -------------------- (audio/raw)
- ! (--------) !
- (----------------------------------------------------------------)
-
-
-
-TODO
-----
-
-automatically generate the padtemplates from all possible avi types
-found in the registry.
-
-
--- a/gst_plugins_good/gst/avi/avi-ids.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AVI_H__
-#define __GST_AVI_H__
-
-#include <gst/gst.h>
-
-typedef struct _gst_riff_avih {
- guint32 us_frame; /* microsec per frame */
- guint32 max_bps; /* byte/s overall */
- guint32 pad_gran; /* pad_granularity */
- guint32 flags;
-/* flags values */
-#define GST_RIFF_AVIH_HASINDEX 0x00000010 /* has idx1 chunk */
-#define GST_RIFF_AVIH_MUSTUSEINDEX 0x00000020 /* must use idx1 chunk to determine order */
-#define GST_RIFF_AVIH_ISINTERLEAVED 0x00000100 /* AVI file is interleaved */
-#define GST_RIFF_AVIH_WASCAPTUREFILE 0x00010000 /* specially allocated used for capturing real time video */
-#define GST_RIFF_AVIH_COPYRIGHTED 0x00020000 /* contains copyrighted data */
- guint32 tot_frames; /* # of frames (all) */
- guint32 init_frames; /* initial frames (???) */
- guint32 streams;
- guint32 bufsize; /* suggested buffer size */
- guint32 width;
- guint32 height;
- guint32 scale;
- guint32 rate;
- guint32 start;
- guint32 length;
-} gst_riff_avih;
-
-/* vprp (video properties) ODML header */
-/* see ODML spec for some/more explanation */
-#define GST_RIFF_TAG_vprp GST_MAKE_FOURCC ('v','p','r','p')
-#define GST_RIFF_VPRP_VIDEO_FIELDS (2)
-
-typedef struct _gst_riff_vprp_video_field_desc {
- guint32 compressed_bm_height;
- guint32 compressed_bm_width;
- guint32 valid_bm_height;
- guint32 valid_bm_width;
- guint32 valid_bm_x_offset;
- guint32 valid_bm_y_offset;
- guint32 video_x_t_offset;
- guint32 video_y_start;
-} gst_riff_vprp_video_field_desc;
-
-typedef struct _gst_riff_vprp {
- guint32 format_token; /* whether fields defined by standard */
- guint32 standard; /* video display standard, UNKNOWN, PAL, etc */
- guint32 vert_rate; /* vertical refresh rate */
- guint32 hor_t_total; /* width */
- guint32 vert_lines; /* height */
- guint32 aspect; /* aspect ratio high word:low word */
- guint32 width; /* active width */
- guint32 height; /* active height */
- guint32 fields; /* field count */
- gst_riff_vprp_video_field_desc field_info[GST_RIFF_VPRP_VIDEO_FIELDS];
-} gst_riff_vprp;
-
-#endif /* __GST_AVI_H__ */
--- a/gst_plugins_good/gst/avi/gstavi.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@temple-baptist.com>
- *
- * gstavi.c: plugin registering
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gst/gst-i18n-plugin.h"
-
-#include "gstavidemux.h"
-#include "gstavimux.h"
-#include "gstavisubtitle.h"
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- gst_riff_init ();
-
-#ifdef ENABLE_NLS
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif /* ENABLE_NLS */
-
- if (!gst_element_register (plugin, "avidemux", GST_RANK_PRIMARY,
- GST_TYPE_AVI_DEMUX) ||
- !gst_element_register (plugin, "avimux", GST_RANK_PRIMARY,
- GST_TYPE_AVI_MUX) ||
- !gst_element_register (plugin, "avisubtitle", GST_RANK_PRIMARY,
- GST_TYPE_AVI_SUBTITLE)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "avi",
- "AVI stream handling",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-#ifdef SYMBIAN
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
-#endif
--- a/gst_plugins_good/gst/avi/gstavidemux.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4574 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@temple-baptist.com>
- * Copyright (C) <2006> Nokia Corporation (contact <stefan.kost@nokia.com>)
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/* Element-Checklist-Version: 5 */
-
-/**
- * SECTION:element-avidemux
- *
- * Demuxes an .avi file into raw or compressed audio and/or video streams.
- *
- * This element supports both push and pull-based scheduling, depending on the
- * capabilities of the upstream elements.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch filesrc location=test.avi ! avidemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
- * ]| Play (parse and decode) an .avi file and try to output it to
- * an automatically detected soundcard and videosink. If the AVI file contains
- * compressed audio or video data, this will only work if you have the
- * right decoder elements/plugins installed.
- * </refsect2>
- *
- * Last reviewed on 2006-12-29 (0.10.6)
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gst/riff/riff-media.h"
-#include "gstavidemux.h"
-#include "avi-ids.h"
-#include <gst/gst-i18n-plugin.h>
-#include <gst/base/gstadapter.h>
-
-GST_DEBUG_CATEGORY_STATIC (avidemux_debug);
-#define GST_CAT_DEFAULT avidemux_debug
-
-GST_DEBUG_CATEGORY_EXTERN (GST_CAT_EVENT);
-
-static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-msvideo")
- );
-
-static void gst_avi_demux_base_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_class_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_init (GstAviDemux * avi);
-static void gst_avi_demux_finalize (GObject * object);
-
-static void gst_avi_demux_reset (GstAviDemux * avi);
-
-#if 0
-static const GstEventMask *gst_avi_demux_get_event_mask (GstPad * pad);
-#endif
-static gboolean gst_avi_demux_handle_src_event (GstPad * pad, GstEvent * event);
-static gboolean gst_avi_demux_handle_sink_event (GstPad * pad,
- GstEvent * event);
-static gboolean gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event);
-
-#if 0
-static const GstFormat *gst_avi_demux_get_src_formats (GstPad * pad);
-#endif
-static const GstQueryType *gst_avi_demux_get_src_query_types (GstPad * pad);
-static gboolean gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query);
-static gboolean gst_avi_demux_src_convert (GstPad * pad, GstFormat src_format,
- gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
-
-static gboolean gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment);
-static gboolean gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad,
- GstEvent * event);
-static void gst_avi_demux_loop (GstPad * pad);
-static gboolean gst_avi_demux_sink_activate (GstPad * sinkpad);
-static gboolean gst_avi_demux_sink_activate_pull (GstPad * sinkpad,
- gboolean active);
-static gboolean gst_avi_demux_activate_push (GstPad * pad, gboolean active);
-static GstFlowReturn gst_avi_demux_chain (GstPad * pad, GstBuffer * buf);
-
-static GstStateChangeReturn gst_avi_demux_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
-
-/* GObject methods */
-
-GType
-gst_avi_demux_get_type (void)
-{
- static GType avi_demux_type = 0;
-
- if (!avi_demux_type) {
- static const GTypeInfo avi_demux_info = {
- sizeof (GstAviDemuxClass),
- (GBaseInitFunc) gst_avi_demux_base_init,
- NULL,
- (GClassInitFunc) gst_avi_demux_class_init,
- NULL,
- NULL,
- sizeof (GstAviDemux),
- 0,
- (GInstanceInitFunc) gst_avi_demux_init,
- };
-
- avi_demux_type =
- g_type_register_static (GST_TYPE_ELEMENT,
- "GstAviDemux", &avi_demux_info, 0);
- }
-
- return avi_demux_type;
-}
-
-static void
-gst_avi_demux_base_init (GstAviDemuxClass * klass)
-{
- static const GstElementDetails gst_avi_demux_details =
- GST_ELEMENT_DETAILS ("Avi demuxer",
- "Codec/Demuxer",
- "Demultiplex an avi file into audio and video",
- "Erik Walthinsen <omega@cse.ogi.edu>\n"
- "Wim Taymans <wim.taymans@chello.be>\n"
- "Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
- "Thijs Vermeir <thijsvermeir@gmail.com>");
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
- GstCaps *audcaps, *vidcaps, *subcaps;
-
- audcaps = gst_riff_create_audio_template_caps ();
- gst_caps_append (audcaps, gst_caps_new_simple ("audio/x-avi-unknown", NULL));
- audiosrctempl = gst_pad_template_new ("audio_%02d",
- GST_PAD_SRC, GST_PAD_SOMETIMES, audcaps);
-
- vidcaps = gst_riff_create_video_template_caps ();
- gst_caps_append (vidcaps, gst_riff_create_iavs_template_caps ());
- gst_caps_append (vidcaps, gst_caps_new_simple ("video/x-avi-unknown", NULL));
- videosrctempl = gst_pad_template_new ("video_%02d",
- GST_PAD_SRC, GST_PAD_SOMETIMES, vidcaps);
-
- subcaps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
- subsrctempl = gst_pad_template_new ("subtitle_%02d",
- GST_PAD_SRC, GST_PAD_SOMETIMES, subcaps);
- gst_element_class_add_pad_template (element_class, audiosrctempl);
- gst_element_class_add_pad_template (element_class, videosrctempl);
- gst_element_class_add_pad_template (element_class, subsrctempl);
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_templ));
- gst_element_class_set_details (element_class, &gst_avi_demux_details);
-}
-
-static void
-gst_avi_demux_class_init (GstAviDemuxClass * klass)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
- 0, "Demuxer for AVI streams");
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_avi_demux_finalize;
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_avi_demux_change_state);
-}
-
-static void
-gst_avi_demux_init (GstAviDemux * avi)
-{
- avi->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
- gst_pad_set_activate_function (avi->sinkpad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_sink_activate));
- gst_pad_set_activatepull_function (avi->sinkpad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_sink_activate_pull));
- gst_pad_set_activatepush_function (avi->sinkpad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_activate_push));
- gst_pad_set_chain_function (avi->sinkpad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_chain));
- gst_pad_set_event_function (avi->sinkpad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_handle_sink_event));
- gst_element_add_pad (GST_ELEMENT (avi), avi->sinkpad);
-
- avi->adapter = gst_adapter_new ();
-
- gst_avi_demux_reset (avi);
-}
-
-static void
-gst_avi_demux_finalize (GObject * object)
-{
- GstAviDemux *avi = GST_AVI_DEMUX (object);
-
- GST_DEBUG ("AVI: finalize");
-
- g_object_unref (avi->adapter);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_avi_demux_reset (GstAviDemux * avi)
-{
- gint i;
-
- GST_DEBUG ("AVI: reset");
-
- for (i = 0; i < avi->num_streams; i++) {
- g_free (avi->stream[i].strh);
- g_free (avi->stream[i].strf.data);
- if (avi->stream[i].name)
- g_free (avi->stream[i].name);
- if (avi->stream[i].initdata)
- gst_buffer_unref (avi->stream[i].initdata);
- if (avi->stream[i].extradata)
- gst_buffer_unref (avi->stream[i].extradata);
- if (avi->stream[i].pad) {
- gst_pad_set_active (avi->stream[i].pad, FALSE);
- gst_element_remove_pad (GST_ELEMENT (avi), avi->stream[i].pad);
- }
- if (avi->stream[i].taglist) {
- gst_tag_list_free (avi->stream[i].taglist);
- avi->stream[i].taglist = NULL;
- }
- }
- memset (&avi->stream, 0, sizeof (avi->stream));
-
- avi->header_state = GST_AVI_DEMUX_HEADER_TAG_LIST;
- avi->num_streams = 0;
- avi->num_v_streams = 0;
- avi->num_a_streams = 0;
- avi->num_t_streams = 0;
-
- avi->state = GST_AVI_DEMUX_START;
- avi->offset = 0;
-
- g_free (avi->index_entries);
- avi->index_entries = NULL;
- avi->index_size = 0;
- avi->index_offset = 0;
- avi->current_entry = 0;
- g_free (avi->avih);
- avi->avih = NULL;
-
- if (avi->seek_event) {
- gst_event_unref (avi->seek_event);
- avi->seek_event = NULL;
- }
-
- if (avi->globaltags)
- gst_tag_list_free (avi->globaltags);
- avi->globaltags = NULL;
-
- avi->got_tags = TRUE; /* we always want to push global tags */
- avi->have_eos = FALSE;
-
- gst_adapter_clear (avi->adapter);
-
- gst_segment_init (&avi->segment, GST_FORMAT_TIME);
-}
-
-/* Index helper */
-static gst_avi_index_entry *
-gst_avi_demux_index_last (GstAviDemux * avi, gint stream_nr)
-{
- gint i;
- gst_avi_index_entry *result = NULL;
-
- for (i = avi->index_size - 1; i >= 0; i--) {
- if (avi->index_entries[i].stream_nr == stream_nr) {
- result = &avi->index_entries[i];
- break;
- }
- }
- return result;
-}
-
-static gst_avi_index_entry *
-gst_avi_demux_index_next (GstAviDemux * avi, gint stream_nr, gint last,
- guchar flags)
-{
- gint i;
- gst_avi_index_entry *result = NULL, *entry;
-
- for (i = last + 1; i < avi->index_size; i++) {
- entry = &avi->index_entries[i];
-
- if (entry->stream_nr != stream_nr)
- continue;
-
- if ((entry->flags & flags) == flags) {
- result = entry;
- break;
- }
- }
- return result;
-}
-
-static gst_avi_index_entry *
-gst_avi_demux_index_prev (GstAviDemux * avi, gint stream_nr, gint last,
- guchar flags)
-{
- gint i;
- gst_avi_index_entry *result = NULL, *entry;
-
- for (i = last - 1; i >= 0; i--) {
- entry = &avi->index_entries[i];
-
- if (entry->stream_nr != stream_nr)
- continue;
-
- if ((entry->flags & flags) == flags) {
- result = entry;
- break;
- }
- }
- return result;
-}
-
-static gint
-gst_avi_demux_index_entry_search (gst_avi_index_entry * entry, guint64 * time)
-{
- if (entry->ts < *time)
- return -1;
- else if (entry->ts > *time)
- return 1;
- return 0;
-}
-
-/*
- * gst_avi_index_entry:
- * @avi: Avi object
- * @stream_nr: stream number
- * @time: seek time position
- *
- * Finds the index entry which time is less or equal than the requested time.
- *
- * Returns: the found index entry or %NULL
- */
-static gst_avi_index_entry *
-gst_avi_demux_index_entry_for_time (GstAviDemux * avi,
- gint stream_nr, guint64 time)
-{
- gst_avi_index_entry *entry = NULL;
- guint n;
-
- GST_LOG_OBJECT (avi, "stream_nr:%d , time:%" GST_TIME_FORMAT,
- stream_nr, GST_TIME_ARGS (time));
-
- entry = gst_util_array_binary_search (avi->index_entries,
- avi->index_size,
- sizeof (gst_avi_index_entry),
- (GCompareDataFunc) gst_avi_demux_index_entry_search,
- GST_SEARCH_MODE_BEFORE, &time, NULL);
-
- n = entry - avi->index_entries;
- if (entry == NULL) {
- entry = &avi->index_entries[0];
- n = 0;
- while (entry->stream_nr != stream_nr && n < avi->index_size - 1) {
- n++;
- entry = &avi->index_entries[n];
- }
- } else if (entry->stream_nr != stream_nr) {
- while (entry->stream_nr != stream_nr && n > 0) {
- n--;
- entry = &avi->index_entries[n];
- }
- }
-
- GST_LOG_OBJECT (avi,
- "best at entry %u / ts:%" GST_TIME_FORMAT " / dur:%" GST_TIME_FORMAT
- " flags:%02x", n, GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (entry->dur),
- entry->flags);
-
- return entry;
-}
-
-/* GstElement methods */
-
-#if 0
-static const GstFormat *
-gst_avi_demux_get_src_formats (GstPad * pad)
-{
- avi_stream_context *stream = gst_pad_get_element_private (pad);
-
- static const GstFormat src_a_formats[] = {
- GST_FORMAT_TIME,
- GST_FORMAT_BYTES,
- GST_FORMAT_DEFAULT,
- 0
- };
- static const GstFormat src_v_formats[] = {
- GST_FORMAT_TIME,
- GST_FORMAT_DEFAULT,
- 0
- };
-
- return (stream->strh->type == GST_RIFF_FCC_auds ?
- src_a_formats : src_v_formats);
-}
-#endif
-
-/* assumes stream->strf.auds->av_bps != 0 */
-static inline GstClockTime
-avi_stream_convert_bytes_to_time_unchecked (avi_stream_context * stream,
- guint64 bytes)
-{
- return gst_util_uint64_scale (bytes, GST_SECOND, stream->strf.auds->av_bps);
-}
-
-/* assumes stream->strh->rate != 0 */
-static inline GstClockTime
-avi_stream_convert_frames_to_time_unchecked (avi_stream_context * stream,
- guint64 frames)
-{
- return gst_util_uint64_scale (frames, stream->strh->scale * GST_SECOND,
- stream->strh->rate);
-}
-
-static gboolean
-gst_avi_demux_src_convert (GstPad * pad,
- GstFormat src_format,
- gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
-{
- avi_stream_context *stream = gst_pad_get_element_private (pad);
- gboolean res = TRUE;
-
- GST_LOG_OBJECT (pad,
- "Received src_format:%s, src_value:%" G_GUINT64_FORMAT
- ", dest_format:%s", gst_format_get_name (src_format), src_value,
- gst_format_get_name (*dest_format));
-
- if (G_UNLIKELY (src_format == *dest_format)) {
- *dest_value = src_value;
- goto done;
- }
- if (G_UNLIKELY (!stream->strh || !stream->strf.data)) {
- res = FALSE;
- goto done;
- }
- if (G_UNLIKELY (stream->strh->type == GST_RIFF_FCC_vids &&
- (src_format == GST_FORMAT_BYTES
- || *dest_format == GST_FORMAT_BYTES))) {
- res = FALSE;
- goto done;
- }
-
- switch (src_format) {
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- *dest_value = gst_util_uint64_scale (src_value,
- (guint64) stream->strf.auds->av_bps, GST_SECOND);
- break;
- case GST_FORMAT_DEFAULT:
- {
- gdouble error;
-
- *dest_value = gst_util_uint64_scale (src_value, stream->strh->rate,
- stream->strh->scale * GST_SECOND);
-
- /* Attempt to round to nearest integer: if the difference is more
- * than 0.5 (less than -0.5), it means that gst_util_uint64_scale()
- * just truncated an integer, while it had to be rounded
- */
- error = *dest_value * GST_SECOND -
- src_value * stream->strh->rate / stream->strh->scale;
- if (error <= -0.5)
- *dest_value += 1;
- break;
- }
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_BYTES:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- if (stream->strf.auds->av_bps != 0) {
- *dest_value = avi_stream_convert_bytes_to_time_unchecked (stream,
- src_value);
- } else
- res = FALSE;
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_DEFAULT:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value =
- avi_stream_convert_frames_to_time_unchecked (stream, src_value);
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- default:
- res = FALSE;
- }
-
-done:
- GST_LOG_OBJECT (pad,
- "Returning res:%d dest_format:%s dest_value:%" G_GUINT64_FORMAT, res,
- gst_format_get_name (*dest_format), *dest_value);
- return res;
-}
-
-static const GstQueryType *
-gst_avi_demux_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType src_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_SEEKING,
- GST_QUERY_CONVERT,
- 0
- };
-
- return src_types;
-}
-
-static gboolean
-gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
-{
- gboolean res = TRUE;
- GstAviDemux *avi = GST_AVI_DEMUX (gst_pad_get_parent (pad));
-
- avi_stream_context *stream = gst_pad_get_element_private (pad);
-
- if (!stream->strh || !stream->strf.data)
- return gst_pad_query_default (pad, query);
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:{
- gint64 pos = 0;
-
- GST_DEBUG ("pos query for stream %d: frames %d, bytes %" G_GUINT64_FORMAT,
- stream->num, stream->current_frame, stream->current_byte);
-
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- if (stream->is_vbr) {
- /* VBR */
- pos = gst_util_uint64_scale ((gint64) stream->current_frame *
- stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate);
- GST_DEBUG_OBJECT (avi, "VBR convert frame %u, time %"
- GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos));
- } else if (stream->strf.auds->av_bps != 0) {
- /* CBR */
- pos = gst_util_uint64_scale (stream->current_byte, GST_SECOND,
- (guint64) stream->strf.auds->av_bps);
- GST_DEBUG_OBJECT (avi,
- "CBR convert bytes %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT,
- stream->current_byte, GST_TIME_ARGS (pos));
- } else if (stream->total_frames != 0 && stream->total_bytes != 0) {
- /* calculate timestamps based on percentage of length */
- guint64 xlen = avi->avih->us_frame *
- avi->avih->tot_frames * GST_USECOND;
-
- if (stream->is_vbr) {
- pos = gst_util_uint64_scale (xlen, stream->current_frame,
- stream->total_frames);
- GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %"
- GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos));
- } else {
- pos = gst_util_uint64_scale (xlen, stream->current_byte,
- stream->total_bytes);
- GST_DEBUG_OBJECT (avi, "CBR perc convert bytes %" G_GUINT64_FORMAT
- ", time %" GST_TIME_FORMAT, stream->current_byte,
- GST_TIME_ARGS (pos));
- }
- } else {
- /* we don't know */
- res = FALSE;
- }
- } else {
- if (stream->strh->rate != 0) {
- pos = gst_util_uint64_scale ((guint64) stream->current_frame *
- stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate);
- } else {
- pos = stream->current_frame * avi->avih->us_frame * GST_USECOND;
- }
- }
- if (res) {
- GST_DEBUG ("pos query : %" GST_TIME_FORMAT, GST_TIME_ARGS (pos));
- gst_query_set_position (query, GST_FORMAT_TIME, pos);
- } else
- GST_WARNING ("pos query failed");
- break;
- }
- case GST_QUERY_DURATION:
- {
- GstFormat fmt;
-
- if (stream->strh->type != GST_RIFF_FCC_auds &&
- stream->strh->type != GST_RIFF_FCC_vids) {
- res = FALSE;
- break;
- }
-
- gst_query_parse_duration (query, &fmt, NULL);
-
- switch (fmt) {
- case GST_FORMAT_TIME:
- gst_query_set_duration (query, fmt, stream->duration);
- break;
- case GST_FORMAT_DEFAULT:
- {
- gint64 dur;
- GST_DEBUG_OBJECT (query, "total frames is %" G_GUINT32_FORMAT,
- stream->total_frames);
-
- if (stream->total_frames >= 0)
- gst_query_set_duration (query, fmt, stream->total_frames);
- else if (gst_pad_query_convert (pad, GST_FORMAT_TIME,
- stream->duration, &fmt, &dur))
- gst_query_set_duration (query, fmt, dur);
- break;
- }
- default:
- res = FALSE;
- break;
- }
- break;
- }
- case GST_QUERY_SEEKING:{
- GstFormat fmt;
-
- gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
- if (fmt == GST_FORMAT_TIME) {
- gboolean seekable = TRUE;
-
- if (avi->streaming) {
- seekable = FALSE;
- } else {
- if (avi->index_entries == NULL) {
- seekable = FALSE;
- /* FIXME: when building index_entried, count keyframes
- if (!(avi->key_frame_ct > 1))
- seekable = FALSE;
- */
- }
- }
-
- gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
- 0, stream->duration);
- res = TRUE;
- }
- break;
- }
- case GST_QUERY_CONVERT:{
- GstFormat src_fmt, dest_fmt;
- gint64 src_val, dest_val;
-
- gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- if ((res = gst_avi_demux_src_convert (pad, src_fmt, src_val, &dest_fmt,
- &dest_val)))
- gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
- else
- res = gst_pad_query_default (pad, query);
- break;
- }
- default:
- res = gst_pad_query_default (pad, query);
- break;
- }
-
- gst_object_unref (avi);
- return res;
-}
-
-#if 0
-static const GstEventMask *
-gst_avi_demux_get_event_mask (GstPad * pad)
-{
- static const GstEventMask masks[] = {
- {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_KEY_UNIT},
- {0,}
- };
-
- return masks;
-}
-#endif
-
-static gboolean
-gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
-{
- gboolean res = TRUE;
- GstAviDemux *avi = GST_AVI_DEMUX (gst_pad_get_parent (pad));
-
- GST_DEBUG_OBJECT (avi,
- "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- /* Drop NEWSEGMENT events, new ones are generated later */
- gst_event_unref (event);
- break;
- case GST_EVENT_EOS:
- {
- if (avi->state != GST_AVI_DEMUX_MOVI) {
- gst_event_unref (event);
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX,
- (NULL), ("got eos and didn't receive a complete header object"));
- } else if (!gst_avi_demux_push_event (avi, event)) {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX,
- (NULL), ("got eos but no streams (yet)"));
- }
- break;
- }
- default:
- res = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (avi);
-
- return res;
-}
-
-static gboolean
-gst_avi_demux_handle_src_event (GstPad * pad, GstEvent * event)
-{
- gboolean res = TRUE;
- GstAviDemux *avi = GST_AVI_DEMUX (gst_pad_get_parent (pad));
-
- GST_DEBUG_OBJECT (avi,
- "have event type %s: %p on src pad", GST_EVENT_TYPE_NAME (event), event);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEEK:
- /* handle seeking only in pull mode */
- if (!avi->streaming) {
- res = gst_avi_demux_handle_seek (avi, pad, event);
- gst_event_unref (event);
- } else {
- res = gst_pad_event_default (pad, event);
- }
- break;
- case GST_EVENT_QOS:
- case GST_EVENT_NAVIGATION:
- res = FALSE;
- gst_event_unref (event);
- break;
- default:
- res = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (avi);
-
- return res;
-}
-
-/* streaming helper (push) */
-
-/*
- * gst_avi_demux_peek_chunk_info:
- * @avi: Avi object
- * @tag: holder for tag
- * @size: holder for tag size
- *
- * Peek next chunk info (tag and size)
- *
- * Returns: TRUE when one chunk info has been got
- */
-static gboolean
-gst_avi_demux_peek_chunk_info (GstAviDemux * avi, guint32 * tag, guint32 * size)
-{
- const guint8 *data = NULL;
-
- if (gst_adapter_available (avi->adapter) < 8) {
- return FALSE;
- }
-
- data = gst_adapter_peek (avi->adapter, 8);
- *tag = GST_READ_UINT32_LE (data);
- *size = GST_READ_UINT32_LE (data + 4);
-
- return TRUE;
-}
-
-/*
- * gst_avi_demux_peek_chunk:
- * @avi: Avi object
- * @tag: holder for tag
- * @size: holder for tag size
- *
- * Peek enough data for one full chunk
- *
- * Returns: %TRUE when one chunk has been got
- */
-static gboolean
-gst_avi_demux_peek_chunk (GstAviDemux * avi, guint32 * tag, guint32 * size)
-{
- guint32 peek_size = 0;
- gint available;
-
- if (!gst_avi_demux_peek_chunk_info (avi, tag, size)) {
- return FALSE;
- }
- /* FIXME: shouldn't this check go to gst_avi_demux_peek_chunk_info() already */
- if (!(*size) || (*size) == -1) {
- GST_INFO ("Invalid chunk size %d for tag %" GST_FOURCC_FORMAT,
- *size, GST_FOURCC_ARGS (*tag));
- return FALSE;
- }
- peek_size = (*size + 1) & ~1;
- available = gst_adapter_available (avi->adapter);
-
- GST_DEBUG ("Need to peek chunk of %d bytes to read chunk %" GST_FOURCC_FORMAT
- ", %d bytes available", *size, GST_FOURCC_ARGS (*tag), available);
-
- if (available >= (8 + peek_size)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-/* AVI init */
-
-/*
- * gst_avi_demux_parse_file_header:
- * @element: caller element (used for errors/debug).
- * @buf: input data to be used for parsing.
- *
- * "Open" a RIFF/AVI file. The buffer should be at least 12
- * bytes long. Takes ownership of @buf.
- *
- * Returns: TRUE if the file is a RIFF/AVI file, FALSE otherwise.
- * Throws an error, caller should error out (fatal).
- */
-static gboolean
-gst_avi_demux_parse_file_header (GstElement * element, GstBuffer * buf)
-{
- guint32 doctype;
-
- /* riff_parse posts an error */
- if (!gst_riff_parse_file_header (element, buf, &doctype))
- return FALSE;
-
- if (doctype != GST_RIFF_RIFF_AVI)
- goto not_avi;
-
- return TRUE;
-
- /* ERRORS */
-not_avi:
- {
- GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
- ("File is not an AVI file: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (doctype)));
- return FALSE;
- }
-}
-
-/*
- * Read AVI file tag when streaming
- */
-static GstFlowReturn
-gst_avi_demux_stream_init_push (GstAviDemux * avi)
-{
- if (gst_adapter_available (avi->adapter) >= 12) {
- GstBuffer *tmp;
-
- tmp = gst_adapter_take_buffer (avi->adapter, 12);
-
- GST_DEBUG ("Parsing avi header");
- if (!gst_avi_demux_parse_file_header (GST_ELEMENT (avi), tmp)) {
- return GST_FLOW_ERROR;
- }
- GST_DEBUG ("header ok");
- avi->offset += 12;
-
- avi->state = GST_AVI_DEMUX_HEADER;
- }
- return GST_FLOW_OK;
-}
-
-/*
- * Read AVI file tag
- */
-static GstFlowReturn
-gst_avi_demux_stream_init_pull (GstAviDemux * avi)
-{
- GstFlowReturn res;
- GstBuffer *buf = NULL;
-
- res = gst_pad_pull_range (avi->sinkpad, avi->offset, 12, &buf);
- if (res != GST_FLOW_OK)
- return res;
- else if (!gst_avi_demux_parse_file_header (GST_ELEMENT_CAST (avi), buf))
- goto wrong_header;
-
- avi->offset += 12;
-
- return GST_FLOW_OK;
-
- /* ERRORS */
-wrong_header:
- {
- GST_DEBUG_OBJECT (avi, "error parsing file header");
- return GST_FLOW_ERROR;
- }
-}
-
-/* AVI header handling */
-
-/*
- * gst_avi_demux_parse_avih:
- * @element: caller element (used for errors/debug).
- * @buf: input data to be used for parsing.
- * @avih: pointer to structure (filled in by function) containing
- * stream information (such as flags, number of streams, etc.).
- *
- * Read 'avih' header. Discards buffer after use.
- *
- * Returns: TRUE on success, FALSE otherwise. Throws an error if
- * the header is invalid. The caller should error out
- * (fatal).
- */
-static gboolean
-gst_avi_demux_parse_avih (GstElement * element,
- GstBuffer * buf, gst_riff_avih ** _avih)
-{
- gst_riff_avih *avih;
-
- if (buf == NULL)
- goto no_buffer;
-
- if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih))
- goto avih_too_small;
-
- avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
-
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
- avih->us_frame = GUINT32_FROM_LE (avih->us_frame);
- avih->max_bps = GUINT32_FROM_LE (avih->max_bps);
- avih->pad_gran = GUINT32_FROM_LE (avih->pad_gran);
- avih->flags = GUINT32_FROM_LE (avih->flags);
- avih->tot_frames = GUINT32_FROM_LE (avih->tot_frames);
- avih->init_frames = GUINT32_FROM_LE (avih->init_frames);
- avih->streams = GUINT32_FROM_LE (avih->streams);
- avih->bufsize = GUINT32_FROM_LE (avih->bufsize);
- avih->width = GUINT32_FROM_LE (avih->width);
- avih->height = GUINT32_FROM_LE (avih->height);
- avih->scale = GUINT32_FROM_LE (avih->scale);
- avih->rate = GUINT32_FROM_LE (avih->rate);
- avih->start = GUINT32_FROM_LE (avih->start);
- avih->length = GUINT32_FROM_LE (avih->length);
-#endif
-
- /* debug stuff */
- GST_INFO_OBJECT (element, "avih tag found:");
- GST_INFO_OBJECT (element, " us_frame %u", avih->us_frame);
- GST_INFO_OBJECT (element, " max_bps %u", avih->max_bps);
- GST_INFO_OBJECT (element, " pad_gran %u", avih->pad_gran);
- GST_INFO_OBJECT (element, " flags 0x%08x", avih->flags);
- GST_INFO_OBJECT (element, " tot_frames %u", avih->tot_frames);
- GST_INFO_OBJECT (element, " init_frames %u", avih->init_frames);
- GST_INFO_OBJECT (element, " streams %u", avih->streams);
- GST_INFO_OBJECT (element, " bufsize %u", avih->bufsize);
- GST_INFO_OBJECT (element, " width %u", avih->width);
- GST_INFO_OBJECT (element, " height %u", avih->height);
- GST_INFO_OBJECT (element, " scale %u", avih->scale);
- GST_INFO_OBJECT (element, " rate %u", avih->rate);
- GST_INFO_OBJECT (element, " start %u", avih->start);
- GST_INFO_OBJECT (element, " length %u", avih->length);
-
- *_avih = avih;
- gst_buffer_unref (buf);
-
- return TRUE;
-
- /* ERRORS */
-no_buffer:
- {
- GST_ELEMENT_ERROR (element, STREAM, DEMUX, (NULL), ("No buffer"));
- return FALSE;
- }
-avih_too_small:
- {
- GST_ELEMENT_ERROR (element, STREAM, DEMUX, (NULL),
- ("Too small avih (%d available, %d needed)",
- GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
- gst_buffer_unref (buf);
- return FALSE;
- }
-}
-
-/*
- * gst_avi_demux_parse_superindex:
- * @avi: caller element (used for debugging/errors).
- * @buf: input data to use for parsing.
- * @locations: locations in the file (byte-offsets) that contain
- * the actual indexes (see get_avi_demux_parse_subindex()).
- * The array ends with GST_BUFFER_OFFSET_NONE.
- *
- * Reads superindex (openDML-2 spec stuff) from the provided data.
- *
- * Returns: TRUE on success, FALSE otherwise. Indexes should be skipped
- * on error, but they are not fatal.
- */
-static gboolean
-gst_avi_demux_parse_superindex (GstAviDemux * avi,
- GstBuffer * buf, guint64 ** _indexes)
-{
- guint8 *data;
- guint16 bpe = 16;
- guint32 num, i;
- guint64 *indexes;
- guint size;
-
- *_indexes = NULL;
-
- size = buf ? GST_BUFFER_SIZE (buf) : 0;
- if (size < 24)
- goto too_small;
-
- data = GST_BUFFER_DATA (buf);
-
- /* check type of index. The opendml2 specs state that
- * there should be 4 dwords per array entry. Type can be
- * either frame or field (and we don't care). */
- if (GST_READ_UINT16_LE (data) != 4 ||
- (data[2] & 0xfe) != 0x0 || data[3] != 0x0) {
- GST_WARNING_OBJECT (avi,
- "Superindex for stream has unexpected "
- "size_entry %d (bytes) or flags 0x%02x/0x%02x",
- GST_READ_UINT16_LE (data), data[2], data[3]);
- bpe = GST_READ_UINT16_LE (data) * 4;
- }
- num = GST_READ_UINT32_LE (&data[4]);
-
- indexes = g_new (guint64, num + 1);
- for (i = 0; i < num; i++) {
- if (size < 24 + bpe * (i + 1))
- break;
- indexes[i] = GST_READ_UINT64_LE (&data[24 + bpe * i]);
- }
- indexes[i] = GST_BUFFER_OFFSET_NONE;
- *_indexes = indexes;
-
- gst_buffer_unref (buf);
-
- return TRUE;
-
- /* ERRORS */
-too_small:
- {
- GST_ERROR_OBJECT (avi,
- "Not enough data to parse superindex (%d available, 24 needed)", size);
- if (buf)
- gst_buffer_unref (buf);
- return FALSE;
- }
-}
-
-/*
- * gst_avi_demux_parse_subindex:
- * @avi: Avi object
- * @buf: input data to use for parsing.
- * @stream: stream context.
- * @entries_list: a list (returned by the function) containing all the
- * indexes parsed in this specific subindex. The first
- * entry is also a pointer to allocated memory that needs
- * to be free´ed. May be NULL if no supported indexes were
- * found.
- *
- * Reads superindex (openDML-2 spec stuff) from the provided data.
- * The buffer will be discarded after use.
- *
- * Returns: TRUE on success, FALSE otherwise. Errors are fatal, we
- * throw an error, caller should bail out asap.
- */
-static gboolean
-gst_avi_demux_parse_subindex (GstAviDemux * avi,
- GstBuffer * buf, avi_stream_context * stream, GList ** _entries_list)
-{
- guint8 *data = GST_BUFFER_DATA (buf);
- guint16 bpe;
- guint32 num, i;
- guint64 baseoff;
- gst_avi_index_entry *entries, *entry;
- GList *entries_list = NULL;
- guint size;
-
- *_entries_list = NULL;
-
- size = buf ? GST_BUFFER_SIZE (buf) : 0;
-
- /* check size */
- if (size < 24)
- goto too_small;
-
- /* We don't support index-data yet */
- if (data[3] & 0x80)
- goto not_implemented;
-
- /* check type of index. The opendml2 specs state that
- * there should be 4 dwords per array entry. Type can be
- * either frame or field (and we don't care). */
- bpe = (data[2] & 0x01) ? 12 : 8;
- if (GST_READ_UINT16_LE (data) != bpe / 4 ||
- (data[2] & 0xfe) != 0x0 || data[3] != 0x1) {
- GST_WARNING_OBJECT (avi,
- "Superindex for stream %d has unexpected "
- "size_entry %d (bytes) or flags 0x%02x/0x%02x",
- stream->num, GST_READ_UINT16_LE (data), data[2], data[3]);
- bpe = GST_READ_UINT16_LE (data) * 4;
- }
- num = GST_READ_UINT32_LE (&data[4]);
- baseoff = GST_READ_UINT64_LE (&data[12]);
-
- /* If there's nothing, just return ! */
- if (num == 0)
- return TRUE;
-
- if (!(entries = g_try_new (gst_avi_index_entry, num)))
- goto out_of_mem;
-
- for (i = 0; i < num; i++) {
- gint64 next_ts;
-
- entry = &entries[i];
-
- if (size < 24 + bpe * (i + 1))
- break;
-
- /* fill in */
- entry->offset = baseoff + GST_READ_UINT32_LE (&data[24 + bpe * i]);
- entry->size = GST_READ_UINT32_LE (&data[24 + bpe * i + 4]);
- entry->flags =
- (entry->size & 0x80000000) ? 0 : GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME;
- entry->size &= ~0x80000000;
- entry->index_nr = i;
- entry->stream_nr = stream->num;
-
- /* stream duration unknown, now we can calculate it */
- if (stream->idx_duration == -1)
- stream->idx_duration = 0;
-
- /* timestamps */
- entry->ts = stream->idx_duration;
- if (stream->is_vbr) {
- /* VBR stream next timestamp */
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_blocks + 1);
- } else {
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames + 1);
- }
- } else {
- /* CBR get next timestamp */
- next_ts = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes + entry->size);
- }
- /* duration is next - current */
- entry->dur = next_ts - entry->ts;
-
- /* stream position */
- entry->bytes_before = stream->total_bytes;
- entry->frames_before = stream->total_frames;
-
- stream->total_bytes += entry->size;
- stream->total_frames++;
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- if (stream->strf.auds->blockalign > 0)
- stream->total_blocks +=
- (entry->size + stream->strf.auds->blockalign -
- 1) / stream->strf.auds->blockalign;
- else
- stream->total_blocks++;
- }
- stream->idx_duration = next_ts;
-
- entries_list = g_list_prepend (entries_list, entry);
- }
-
- GST_LOG_OBJECT (avi, "Read %d index entries", i);
-
- gst_buffer_unref (buf);
-
- if (i > 0) {
- *_entries_list = g_list_reverse (entries_list);
- } else {
- g_free (entries);
- }
-
- return TRUE;
-
- /* ERRORS */
-too_small:
- {
- GST_ERROR_OBJECT (avi,
- "Not enough data to parse subindex (%d available, 24 needed)", size);
- if (buf)
- gst_buffer_unref (buf);
- return TRUE; /* continue */
- }
-not_implemented:
- {
- GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
- ("Subindex-is-data is not implemented"));
- gst_buffer_unref (buf);
- return FALSE;
- }
-out_of_mem:
- {
- GST_ELEMENT_ERROR (avi, RESOURCE, NO_SPACE_LEFT, (NULL),
- ("Cannot allocate memory for %u*%u=%u bytes",
- (guint) sizeof (gst_avi_index_entry), num,
- (guint) sizeof (gst_avi_index_entry) * num));
- gst_buffer_unref (buf);
- return FALSE;
- }
-}
-
-#if 0
-/*
- * Read AVI index when streaming
- */
-static void
-gst_avi_demux_read_subindexes_push (GstAviDemux * avi,
- GList ** index, GList ** alloc_list)
-{
- GList *list = NULL;
- guint32 tag = 0, size;
- GstBuffer *buf = NULL;
- gint i, n;
-
- GST_DEBUG_OBJECT (avi, "gst_avi_demux_read_subindexes_push for %d streams",
- avi->num_streams);
-
- for (n = 0; n < avi->num_streams; n++) {
- avi_stream_context *stream = &avi->stream[n];
-
- for (i = 0; stream->indexes[i] != GST_BUFFER_OFFSET_NONE; i++) {
- if (!gst_avi_demux_peek_chunk (avi, &tag, &size))
- continue;
- else if ((tag != GST_MAKE_FOURCC ('i', 'x', '0' + stream->num / 10,
- '0' + stream->num % 10)) &&
- (tag != GST_MAKE_FOURCC ('0' + stream->num / 10,
- '0' + stream->num % 10, 'i', 'x'))) {
- GST_WARNING_OBJECT (avi, "Not an ix## chunk (%" GST_FOURCC_FORMAT ")",
- GST_FOURCC_ARGS (tag));
- continue;
- }
-
- avi->offset += 8 + ((size + 1) & ~1);
-
- buf = gst_buffer_new ();
- GST_BUFFER_DATA (buf) = gst_adapter_take (avi->adapter, size);
- GST_BUFFER_SIZE (buf) = size;
-
- if (!gst_avi_demux_parse_subindex (avi, buf, stream, &list))
- continue;
- if (list) {
- GST_DEBUG_OBJECT (avi, " adding %d entries", g_list_length (list));
- *alloc_list = g_list_append (*alloc_list, list->data);
- *index = g_list_concat (*index, list);
- }
- }
-
- g_free (stream->indexes);
- stream->indexes = NULL;
- }
- GST_DEBUG_OBJECT (avi, "index %s", ((*index) ? "!= 0" : "== 0"));
-}
-#endif
-
-/*
- * Read AVI index
- */
-static void
-gst_avi_demux_read_subindexes_pull (GstAviDemux * avi,
- GList ** index, GList ** alloc_list)
-{
- GList *list = NULL;
- guint32 tag;
- GstBuffer *buf;
- gint i, n;
-
- GST_DEBUG_OBJECT (avi, "gst_avi_demux_read_subindexes_pull for %d streams",
- avi->num_streams);
-
- for (n = 0; n < avi->num_streams; n++) {
- avi_stream_context *stream = &avi->stream[n];
-
- for (i = 0; stream->indexes[i] != GST_BUFFER_OFFSET_NONE; i++) {
- if (gst_riff_read_chunk (GST_ELEMENT (avi), avi->sinkpad,
- &stream->indexes[i], &tag, &buf) != GST_FLOW_OK)
- continue;
- else if ((tag != GST_MAKE_FOURCC ('i', 'x', '0' + stream->num / 10,
- '0' + stream->num % 10)) &&
- (tag != GST_MAKE_FOURCC ('0' + stream->num / 10,
- '0' + stream->num % 10, 'i', 'x'))) {
- /* Some ODML files (created by god knows what muxer) have a ##ix format
- * instead of the 'official' ix##. They are still valid though. */
- GST_WARNING_OBJECT (avi, "Not an ix## chunk (%" GST_FOURCC_FORMAT ")",
- GST_FOURCC_ARGS (tag));
- gst_buffer_unref (buf);
- continue;
- }
-
- if (!gst_avi_demux_parse_subindex (avi, buf, stream, &list))
- continue;
- if (list) {
- GST_DEBUG_OBJECT (avi, " adding %5d entries, total %2d %5d",
- g_list_length (list), g_list_length (*alloc_list),
- g_list_length (*index));
- *alloc_list = g_list_append (*alloc_list, list->data);
- *index = g_list_concat (*index, list);
- }
- }
-
- g_free (stream->indexes);
- stream->indexes = NULL;
- }
- GST_DEBUG_OBJECT (avi, "index %s", ((*index) ? "!= 0" : "== 0"));
-}
-
-/*
- * gst_avi_demux_riff_parse_vprp:
- * @element: caller element (used for debugging/error).
- * @buf: input data to be used for parsing, stripped from header.
- * @vprp: a pointer (returned by this function) to a filled-in vprp
- * structure. Caller should free it.
- *
- * Parses a video stream´s vprp. This function takes ownership of @buf.
- *
- * Returns: TRUE if parsing succeeded, otherwise FALSE. The stream
- * should be skipped on error, but it is not fatal.
- */
-static gboolean
-gst_avi_demux_riff_parse_vprp (GstElement * element,
- GstBuffer * buf, gst_riff_vprp ** _vprp)
-{
- gst_riff_vprp *vprp;
- gint k;
-
- g_return_val_if_fail (buf != NULL, FALSE);
- g_return_val_if_fail (_vprp != NULL, FALSE);
-
- if (GST_BUFFER_SIZE (buf) < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
- goto too_small;
-
- vprp = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
-
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
- vprp->format_token = GUINT32_FROM_LE (vprp->format_token);
- vprp->standard = GUINT32_FROM_LE (vprp->standard);
- vprp->vert_rate = GUINT32_FROM_LE (vprp->vert_rate);
- vprp->hor_t_total = GUINT32_FROM_LE (vprp->hor_t_total);
- vprp->vert_lines = GUINT32_FROM_LE (vprp->vert_lines);
- vprp->aspect = GUINT32_FROM_LE (vprp->aspect);
- vprp->width = GUINT32_FROM_LE (vprp->width);
- vprp->height = GUINT32_FROM_LE (vprp->height);
- vprp->fields = GUINT32_FROM_LE (vprp->fields);
-#endif
-
- /* size checking */
- /* calculate fields based on size */
- k = (GST_BUFFER_SIZE (buf) - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) /
- vprp->fields;
- if (vprp->fields > k) {
- GST_WARNING_OBJECT (element,
- "vprp header indicated %d fields, only %d available", vprp->fields, k);
- vprp->fields = k;
- }
- if (vprp->fields > GST_RIFF_VPRP_VIDEO_FIELDS) {
- GST_WARNING_OBJECT (element,
- "vprp header indicated %d fields, at most %d supported", vprp->fields,
- GST_RIFF_VPRP_VIDEO_FIELDS);
- vprp->fields = GST_RIFF_VPRP_VIDEO_FIELDS;
- }
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
- for (k = 0; k < vprp->fields; k++) {
- gst_riff_vprp_video_field_desc *fd;
-
- fd = &vprp->field_info[k];
- fd->compressed_bm_height = GUINT32_FROM_LE (fd->compressed_bm_height);
- fd->compressed_bm_width = GUINT32_FROM_LE (fd->compressed_bm_width);
- fd->valid_bm_height = GUINT32_FROM_LE (fd->valid_bm_height);
- fd->valid_bm_width = GUINT16_FROM_LE (fd->valid_bm_width);
- fd->valid_bm_x_offset = GUINT16_FROM_LE (fd->valid_bm_x_offset);
- fd->valid_bm_y_offset = GUINT32_FROM_LE (fd->valid_bm_y_offset);
- fd->video_x_t_offset = GUINT32_FROM_LE (fd->video_x_t_offset);
- fd->video_y_start = GUINT32_FROM_LE (fd->video_y_start);
- }
-#endif
-
- /* debug */
- GST_INFO_OBJECT (element, "vprp tag found in context vids:");
- GST_INFO_OBJECT (element, " format_token %d", vprp->format_token);
- GST_INFO_OBJECT (element, " standard %d", vprp->standard);
- GST_INFO_OBJECT (element, " vert_rate %d", vprp->vert_rate);
- GST_INFO_OBJECT (element, " hor_t_total %d", vprp->hor_t_total);
- GST_INFO_OBJECT (element, " vert_lines %d", vprp->vert_lines);
- GST_INFO_OBJECT (element, " aspect %d:%d", vprp->aspect >> 16,
- vprp->aspect & 0xffff);
- GST_INFO_OBJECT (element, " width %d", vprp->width);
- GST_INFO_OBJECT (element, " height %d", vprp->height);
- GST_INFO_OBJECT (element, " fields %d", vprp->fields);
- for (k = 0; k < vprp->fields; k++) {
- gst_riff_vprp_video_field_desc *fd;
-
- fd = &(vprp->field_info[k]);
- GST_INFO_OBJECT (element, " field %u description:", k);
- GST_INFO_OBJECT (element, " compressed_bm_height %d",
- fd->compressed_bm_height);
- GST_INFO_OBJECT (element, " compressed_bm_width %d",
- fd->compressed_bm_width);
- GST_INFO_OBJECT (element, " valid_bm_height %d",
- fd->valid_bm_height);
- GST_INFO_OBJECT (element, " valid_bm_width %d", fd->valid_bm_width);
- GST_INFO_OBJECT (element, " valid_bm_x_offset %d",
- fd->valid_bm_x_offset);
- GST_INFO_OBJECT (element, " valid_bm_y_offset %d",
- fd->valid_bm_y_offset);
- GST_INFO_OBJECT (element, " video_x_t_offset %d",
- fd->video_x_t_offset);
- GST_INFO_OBJECT (element, " video_y_start %d", fd->video_y_start);
- }
-
- gst_buffer_unref (buf);
-
- *_vprp = vprp;
-
- return TRUE;
-
- /* ERRORS */
-too_small:
- {
- GST_ERROR_OBJECT (element,
- "Too small vprp (%d available, at least %d needed)",
- GST_BUFFER_SIZE (buf),
- (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
- gst_buffer_unref (buf);
- return FALSE;
- }
-}
-
-/*
- * gst_avi_demux_parse_stream:
- * @avi: calling element (used for debugging/errors).
- * @buf: input buffer used to parse the stream.
- *
- * Parses all subchunks in a strl chunk (which defines a single
- * stream). Discards the buffer after use. This function will
- * increment the stream counter internally.
- *
- * Returns: whether the stream was identified successfully.
- * Errors are not fatal. It does indicate the stream
- * was skipped.
- */
-static gboolean
-gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
-{
- avi_stream_context *stream;
- GstElementClass *klass;
- GstPadTemplate *templ;
- GstBuffer *sub = NULL;
- guint offset = 4;
- guint32 tag = 0;
- gchar *codec_name = NULL, *padname = NULL;
- const gchar *tag_name;
- GstCaps *caps = NULL;
- GstPad *pad;
- GstElement *element;
- gboolean got_strh = FALSE, got_strf = FALSE, got_vprp = FALSE;
- gst_riff_vprp *vprp = NULL;
-
- element = GST_ELEMENT_CAST (avi);
-
- GST_DEBUG_OBJECT (avi, "Parsing stream");
-
- if (avi->num_streams >= GST_AVI_DEMUX_MAX_STREAMS) {
- GST_WARNING_OBJECT (avi,
- "maximum no of streams (%d) exceeded, ignoring stream",
- GST_AVI_DEMUX_MAX_STREAMS);
- gst_buffer_unref (buf);
- /* not a fatal error, let's say */
- return TRUE;
- }
-
- stream = &avi->stream[avi->num_streams];
-
- /* initial settings */
- stream->idx_duration = GST_CLOCK_TIME_NONE;
- stream->hdr_duration = GST_CLOCK_TIME_NONE;
- stream->duration = GST_CLOCK_TIME_NONE;
-
- while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
- /* sub can be NULL if the chunk is empty */
- if (sub == NULL) {
- GST_DEBUG_OBJECT (avi, "ignoring empty chunk %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (tag));
- continue;
- }
- switch (tag) {
- case GST_RIFF_TAG_strh:
- {
- gst_riff_strh *strh;
-
- if (got_strh) {
- GST_WARNING_OBJECT (avi, "Ignoring additional strh chunk");
- break;
- }
- if (!gst_riff_parse_strh (element, sub, &stream->strh)) {
- /* ownership given away */
- sub = NULL;
- GST_WARNING_OBJECT (avi, "Failed to parse strh chunk");
- goto fail;
- }
- sub = NULL;
- strh = stream->strh;
- /* sanity check; stream header frame rate matches global header
- * frame duration */
- if (stream->strh->type == GST_RIFF_FCC_vids) {
- GstClockTime s_dur;
- GstClockTime h_dur = avi->avih->us_frame * GST_USECOND;
-
- s_dur = gst_util_uint64_scale (GST_SECOND, strh->scale, strh->rate);
- GST_DEBUG_OBJECT (avi, "verifying stream framerate %d/%d, "
- "frame duration = %d ms", strh->rate, strh->scale,
- s_dur / GST_MSECOND);
- if (h_dur > (10 * GST_MSECOND) && (s_dur > 10 * h_dur)) {
- strh->rate = GST_SECOND / GST_USECOND;
- strh->scale = h_dur / GST_USECOND;
- GST_DEBUG_OBJECT (avi, "correcting stream framerate to %d/%d",
- strh->rate, strh->scale);
- }
- }
- /* determine duration as indicated by header */
- stream->hdr_duration = gst_util_uint64_scale ((guint64) strh->length *
- strh->scale, GST_SECOND, (guint64) strh->rate);
- GST_INFO ("Stream duration according to header: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (stream->hdr_duration));
- if (stream->hdr_duration == 0)
- stream->hdr_duration = GST_CLOCK_TIME_NONE;
-
- got_strh = TRUE;
- break;
- }
- case GST_RIFF_TAG_strf:
- {
- gboolean res = FALSE;
-
- if (got_strf) {
- GST_WARNING_OBJECT (avi, "Ignoring additional strf chunk");
- break;
- }
- if (!got_strh) {
- GST_ERROR_OBJECT (avi, "Found strf chunk before strh chunk");
- goto fail;
- }
- switch (stream->strh->type) {
- case GST_RIFF_FCC_vids:
- stream->is_vbr = TRUE;
- res = gst_riff_parse_strf_vids (element, sub,
- &stream->strf.vids, &stream->extradata);
- sub = NULL;
- GST_DEBUG_OBJECT (element, "marking video as VBR, res %d", res);
- break;
- case GST_RIFF_FCC_auds:
- stream->is_vbr = (stream->strh->samplesize == 0)
- && stream->strh->scale > 1;
- res =
- gst_riff_parse_strf_auds (element, sub, &stream->strf.auds,
- &stream->extradata);
- sub = NULL;
- GST_DEBUG_OBJECT (element, "marking audio as VBR:%d, res %d",
- stream->is_vbr, res);
- break;
- case GST_RIFF_FCC_iavs:
- stream->is_vbr = TRUE;
- res = gst_riff_parse_strf_iavs (element, sub,
- &stream->strf.iavs, &stream->extradata);
- sub = NULL;
- GST_DEBUG_OBJECT (element, "marking iavs as VBR, res %d", res);
- break;
- case GST_RIFF_FCC_txts:
- /* nothing to parse here */
- stream->is_vbr = (stream->strh->samplesize == 0)
- && (stream->strh->scale > 1);
- res = TRUE;
- break;
- default:
- GST_ERROR_OBJECT (avi,
- "Don´t know how to handle stream type %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (stream->strh->type));
- break;
- }
- if (sub) {
- gst_buffer_unref (sub);
- sub = NULL;
- }
- if (!res)
- goto fail;
- got_strf = TRUE;
- break;
- }
- case GST_RIFF_TAG_vprp:
- {
- if (got_vprp) {
- GST_WARNING_OBJECT (avi, "Ignoring additional vprp chunk");
- break;
- }
- if (!got_strh) {
- GST_ERROR_OBJECT (avi, "Found vprp chunk before strh chunk");
- goto fail;
- }
- if (!got_strf) {
- GST_ERROR_OBJECT (avi, "Found vprp chunk before strf chunk");
- goto fail;
- }
-
- if (!gst_avi_demux_riff_parse_vprp (element, sub, &vprp)) {
- GST_WARNING_OBJECT (avi, "Failed to parse vprp chunk");
- /* not considered fatal */
- g_free (vprp);
- vprp = NULL;
- } else
- got_vprp = TRUE;
- sub = NULL;
- break;
- }
- case GST_RIFF_TAG_strd:
- if (stream->initdata)
- gst_buffer_unref (stream->initdata);
- stream->initdata = sub;
- sub = NULL;
- break;
- case GST_RIFF_TAG_strn:
- g_free (stream->name);
- if (sub != NULL) {
- stream->name =
- g_strndup ((gchar *) GST_BUFFER_DATA (sub),
- (gsize) GST_BUFFER_SIZE (sub));
- gst_buffer_unref (sub);
- sub = NULL;
- } else {
- stream->name = g_strdup ("");
- }
- GST_DEBUG_OBJECT (avi, "stream name: %s", stream->name);
- break;
- default:
- if (tag == GST_MAKE_FOURCC ('i', 'n', 'd', 'x') ||
- tag == GST_MAKE_FOURCC ('i', 'x', '0' + avi->num_streams / 10,
- '0' + avi->num_streams % 10)) {
- g_free (stream->indexes);
- gst_avi_demux_parse_superindex (avi, sub, &stream->indexes);
- stream->superindex = TRUE;
- sub = NULL;
- break;
- }
- GST_WARNING_OBJECT (avi,
- "Unknown stream header tag %" GST_FOURCC_FORMAT ", ignoring",
- GST_FOURCC_ARGS (tag));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- break;
- }
- if (sub != NULL) {
- gst_buffer_unref (sub);
- sub = NULL;
- }
- }
-
- if (!got_strh) {
- GST_WARNING_OBJECT (avi, "Failed to find strh chunk");
- goto fail;
- }
-
- if (!got_strf) {
- GST_WARNING_OBJECT (avi, "Failed to find strf chunk");
- goto fail;
- }
-
- /* get class to figure out the template */
- klass = GST_ELEMENT_GET_CLASS (avi);
-
- /* we now have all info, let´s set up a pad and a caps and be done */
- /* create stream name + pad */
- switch (stream->strh->type) {
- case GST_RIFF_FCC_vids:{
- guint32 fourcc;
-
- fourcc = (stream->strf.vids->compression) ?
- stream->strf.vids->compression : stream->strh->fcc_handler;
- padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
- templ = gst_element_class_get_pad_template (klass, "video_%02d");
- caps = gst_riff_create_video_caps (fourcc, stream->strh,
- stream->strf.vids, stream->extradata, stream->initdata, &codec_name);
- if (!caps) {
- caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
- GST_TYPE_FOURCC, fourcc, NULL);
- } else if (got_vprp && vprp) {
- guint32 aspect_n, aspect_d;
- gint n, d;
-
- aspect_n = vprp->aspect >> 16;
- aspect_d = vprp->aspect & 0xffff;
- /* calculate the pixel aspect ratio using w/h and aspect ratio */
- n = aspect_n * stream->strf.vids->height;
- d = aspect_d * stream->strf.vids->width;
- if (n && d)
- gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
- n, d, NULL);
- /* very local, not needed elsewhere */
- g_free (vprp);
- vprp = NULL;
- }
- tag_name = GST_TAG_VIDEO_CODEC;
- avi->num_v_streams++;
- break;
- }
- case GST_RIFF_FCC_auds:{
- padname = g_strdup_printf ("audio_%02d", avi->num_a_streams);
- templ = gst_element_class_get_pad_template (klass, "audio_%02d");
- caps = gst_riff_create_audio_caps (stream->strf.auds->format,
- stream->strh, stream->strf.auds, stream->extradata,
- stream->initdata, &codec_name);
- if (!caps) {
- caps = gst_caps_new_simple ("audio/x-avi-unknown", "codec_id",
- G_TYPE_INT, stream->strf.auds->format, NULL);
- }
- tag_name = GST_TAG_AUDIO_CODEC;
- avi->num_a_streams++;
- break;
- }
- case GST_RIFF_FCC_iavs:{
- guint32 fourcc = stream->strh->fcc_handler;
-
- padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
- templ = gst_element_class_get_pad_template (klass, "video_%02d");
- caps = gst_riff_create_iavs_caps (fourcc, stream->strh,
- stream->strf.iavs, stream->extradata, stream->initdata, &codec_name);
- if (!caps) {
- caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
- GST_TYPE_FOURCC, fourcc, NULL);
- }
- tag_name = GST_TAG_VIDEO_CODEC;
- avi->num_v_streams++;
- break;
- }
- case GST_RIFF_FCC_txts:{
- padname = g_strdup_printf ("subtitle_%02d", avi->num_t_streams);
- templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
- caps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
- tag_name = NULL;
- avi->num_t_streams++;
- break;
- }
- default:
- g_assert_not_reached ();
- }
-
- /* no caps means no stream */
- if (!caps) {
- GST_ERROR_OBJECT (element, "Did not find caps for stream %s", padname);
- goto fail;
- }
-
- GST_DEBUG_OBJECT (element, "codec-name=%s",
- (codec_name ? codec_name : "NULL"));
- GST_DEBUG_OBJECT (element, "caps=%" GST_PTR_FORMAT, caps);
-
- /* set proper settings and add it */
- if (stream->pad)
- gst_object_unref (stream->pad);
- pad = stream->pad = gst_pad_new_from_template (templ, padname);
- stream->last_flow = GST_FLOW_OK;
- stream->discont = TRUE;
- g_free (padname);
-
- gst_pad_use_fixed_caps (pad);
-#if 0
- gst_pad_set_formats_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_formats));
- gst_pad_set_event_mask_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_get_event_mask));
-#endif
- gst_pad_set_event_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_event));
- gst_pad_set_query_type_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_query_types));
- gst_pad_set_query_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_query));
-#if 0
- gst_pad_set_convert_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_src_convert));
-#endif
-
- stream->num = avi->num_streams;
- stream->total_bytes = 0;
- stream->total_frames = 0;
- stream->total_blocks = 0;
- stream->current_frame = 0;
- stream->current_byte = 0;
- gst_pad_set_element_private (pad, stream);
- avi->num_streams++;
- gst_pad_set_caps (pad, caps);
- gst_pad_set_active (pad, TRUE);
- gst_element_add_pad (GST_ELEMENT (avi), pad);
- GST_LOG_OBJECT (element, "Added pad %s with caps %" GST_PTR_FORMAT,
- GST_PAD_NAME (pad), caps);
- gst_caps_unref (caps);
-
- /* make tags */
- if (codec_name) {
- if (!stream->taglist)
- stream->taglist = gst_tag_list_new ();
-
- avi->got_tags = TRUE;
-
- gst_tag_list_add (stream->taglist, GST_TAG_MERGE_APPEND, tag_name,
- codec_name, NULL);
- g_free (codec_name);
- }
-
- gst_buffer_unref (buf);
-
- return TRUE;
-
- /* ERRORS */
-fail:
- {
- /* unref any mem that may be in use */
- if (buf)
- gst_buffer_unref (buf);
- if (sub)
- gst_buffer_unref (sub);
- g_free (vprp);
- g_free (codec_name);
- g_free (stream->strh);
- g_free (stream->strf.data);
- g_free (stream->name);
- g_free (stream->indexes);
- if (stream->initdata)
- gst_buffer_unref (stream->initdata);
- if (stream->extradata)
- gst_buffer_unref (stream->extradata);
- memset (stream, 0, sizeof (avi_stream_context));
- avi->num_streams++;
- return FALSE;
- }
-}
-
-/*
- * gst_avi_demux_parse_odml:
- * @avi: calling element (used for debug/error).
- * @buf: input buffer to be used for parsing.
- *
- * Read an openDML-2.0 extension header. Fills in the frame number
- * in the avi demuxer object when reading succeeds.
- */
-static void
-gst_avi_demux_parse_odml (GstAviDemux * avi, GstBuffer * buf)
-{
- guint32 tag = 0;
- guint offset = 4;
- GstBuffer *sub = NULL;
-
- while (gst_riff_parse_chunk (GST_ELEMENT_CAST (avi), buf, &offset, &tag,
- &sub)) {
- switch (tag) {
- case GST_RIFF_TAG_dmlh:{
- gst_riff_dmlh dmlh, *_dmlh;
- guint size;
-
- /* sub == NULL is possible and means an empty buffer */
- size = sub ? GST_BUFFER_SIZE (sub) : 0;
-
- /* check size */
- if (size < sizeof (gst_riff_dmlh)) {
- GST_ERROR_OBJECT (avi,
- "DMLH entry is too small (%d bytes, %d needed)",
- size, (int) sizeof (gst_riff_dmlh));
- goto next;
- }
- _dmlh = (gst_riff_dmlh *) GST_BUFFER_DATA (sub);
- dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes);
-
- GST_INFO_OBJECT (avi, "dmlh tag found:");
- GST_INFO_OBJECT (avi, " totalframes: %u", dmlh.totalframes);
-
- avi->avih->tot_frames = dmlh.totalframes;
- goto next;
- }
-
- default:
- GST_WARNING_OBJECT (avi,
- "Unknown tag %" GST_FOURCC_FORMAT " in ODML header",
- GST_FOURCC_ARGS (tag));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- next:
- /* skip and move to next chunk */
- if (sub) {
- gst_buffer_unref (sub);
- sub = NULL;
- }
- break;
- }
- }
- if (buf)
- gst_buffer_unref (buf);
-}
-
-/*
- * Sort helper for index entries that sorts by index time.
- * If times are equal we sort by stream number.
- */
-static gint
-sort (gst_avi_index_entry * a, gst_avi_index_entry * b)
-{
- if (a->ts > b->ts)
- return 1;
- else if (a->ts < b->ts)
- return -1;
- else
- return a->stream_nr - b->stream_nr;
-}
-
-/*
- * gst_avi_demux_parse_index:
- * @avi: calling element (used for debugging/errors).
- * @buf: buffer containing the full index.
- * @entries_list: list (returned by this function) containing the index
- * entries parsed from the buffer. The first in the list
- * is also a pointer to the allocated data and should be
- * free'ed at some point.
- *
- * Read index entries from the provided buffer. Takes ownership of @buf.
- */
-static void
-gst_avi_demux_parse_index (GstAviDemux * avi,
- GstBuffer * buf, GList ** _entries_list)
-{
- guint64 pos_before = avi->offset;
- gst_avi_index_entry *entries = NULL;
- guint8 *data;
- GList *entries_list = NULL;
- guint i, num, n;
-
-#ifndef GST_DISABLE_GST_DEBUG
- gulong _nr_keyframes = 0;
-#endif
-
- if (!buf || !GST_BUFFER_SIZE (buf)) {
- *_entries_list = NULL;
- GST_DEBUG ("empty index");
- if (buf)
- gst_buffer_unref (buf);
- return;
- }
-
- data = GST_BUFFER_DATA (buf);
- num = GST_BUFFER_SIZE (buf) / sizeof (gst_riff_index_entry);
- if (!(entries = g_try_new (gst_avi_index_entry, num)))
- goto out_of_mem;
-
- GST_INFO ("Parsing index, nr_entries = %6d", num);
-
- for (i = 0, n = 0; i < num; i++) {
- gint64 next_ts;
- gst_riff_index_entry entry, *_entry;
- avi_stream_context *stream;
- guint stream_nr;
- gst_avi_index_entry *target;
-
- _entry = &((gst_riff_index_entry *) data)[i];
- entry.id = GST_READ_UINT32_LE (&_entry->id);
- entry.offset = GST_READ_UINT32_LE (&_entry->offset);
- entry.flags = GST_READ_UINT32_LE (&_entry->flags);
- entry.size = GST_READ_UINT32_LE (&_entry->size);
- target = &entries[n];
-
- if (entry.id == GST_RIFF_rec || entry.id == 0 ||
- (entry.offset == 0 && n > 0))
- continue;
-
- stream_nr = CHUNKID_TO_STREAMNR (entry.id);
- if (stream_nr >= avi->num_streams) {
- GST_WARNING_OBJECT (avi,
- "Index entry %d has invalid stream nr %d", i, stream_nr);
- continue;
- }
- target->stream_nr = stream_nr;
- stream = &avi->stream[stream_nr];
-
- if (!stream->strh) {
- GST_WARNING_OBJECT (avi, "Unhandled stream %d, skipping", stream_nr);
- continue;
- }
-
- target->index_nr = i;
- target->flags =
- (entry.flags & GST_RIFF_IF_KEYFRAME) ? GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME
- : 0;
- target->size = entry.size;
- target->offset = entry.offset + 8;
-
- /* figure out if the index is 0 based or relative to the MOVI start */
- if (n == 0) {
- if (target->offset < pos_before)
- avi->index_offset = pos_before + 8;
- else
- avi->index_offset = 0;
- GST_DEBUG ("index_offset = %" G_GUINT64_FORMAT, avi->index_offset);
- }
-
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- /* all audio frames are keyframes */
- target->flags |= GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME;
- }
-#ifndef GST_DISABLE_GST_DEBUG
- if (target->flags & GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME)
- _nr_keyframes++;
-#endif
-
- /* stream duration unknown, now we can calculate it */
- if (stream->idx_duration == -1)
- stream->idx_duration = 0;
-
- /* timestamps */
- target->ts = stream->idx_duration;
- if (stream->is_vbr) {
- /* VBR stream next timestamp */
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_blocks + 1);
- } else {
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames + 1);
- }
- } else {
- /* constant rate stream */
- next_ts = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes + target->size);
- }
- /* duration is next - current */
- target->dur = next_ts - target->ts;
-
- /* stream position */
- target->bytes_before = stream->total_bytes;
- target->frames_before = stream->total_frames;
-
- stream->total_bytes += target->size;
- stream->total_frames++;
- if (stream->strh->type == GST_RIFF_FCC_auds) {
- if (stream->strf.auds->blockalign > 0)
- stream->total_blocks +=
- (target->size + stream->strf.auds->blockalign -
- 1) / stream->strf.auds->blockalign;
- else
- stream->total_blocks++;
- }
- stream->idx_duration = next_ts;
-
- GST_LOG_OBJECT (avi,
- "Adding index entry %d (%6u), flags %02x, stream %d, size %u "
- ", offset %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT ", dur %"
- GST_TIME_FORMAT,
- target->index_nr, stream->total_frames - 1, target->flags,
- target->stream_nr, target->size, target->offset,
- GST_TIME_ARGS (target->ts), GST_TIME_ARGS (target->dur));
- entries_list = g_list_prepend (entries_list, target);
-
- n++;
- }
-
- GST_INFO ("Parsed index, %6d entries, %5ld keyframes, entry size = %2d, "
- "total size = %10d", num, _nr_keyframes,
- (gint) sizeof (gst_avi_index_entry),
- (gint) (num * sizeof (gst_avi_index_entry)));
-
- gst_buffer_unref (buf);
-
- if (n > 0) {
- *_entries_list = g_list_reverse (entries_list);
- } else {
- g_free (entries);
- }
- return;
-
- /* ERRORS */
-out_of_mem:
- {
- GST_ELEMENT_ERROR (avi, RESOURCE, NO_SPACE_LEFT, (NULL),
- ("Cannot allocate memory for %u*%u=%u bytes",
- (guint) sizeof (gst_avi_index_entry), num,
- (guint) sizeof (gst_avi_index_entry) * num));
- gst_buffer_unref (buf);
- }
-}
-
-/*
- * gst_avi_demux_stream_index:
- * @avi: avi demuxer object.
- * @index: list of index entries, returned by this function.
- * @alloc_list: list of allocated data, returned by this function.
- *
- * Seeks to index and reads it.
- */
-static void
-gst_avi_demux_stream_index (GstAviDemux * avi,
- GList ** index, GList ** alloc_list)
-{
- GstFlowReturn res;
- guint64 offset = avi->offset;
- GstBuffer *buf;
- guint32 tag;
- guint32 size;
- gint i;
-
- GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
-
- *alloc_list = NULL;
- *index = NULL;
-
- /* get chunk information */
- res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
- if (res != GST_FLOW_OK)
- goto pull_failed;
- else if (GST_BUFFER_SIZE (buf) < 8)
- goto too_small;
-
- /* check tag first before blindy trying to read 'size' bytes */
- tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
- if (tag == GST_RIFF_TAG_LIST) {
- /* this is the movi tag */
- GST_DEBUG_OBJECT (avi, "skip LIST chunk, size %" G_GUINT32_FORMAT,
- (8 + ((size + 1) & ~1)));
- offset += 8 + ((size + 1) & ~1);
- gst_buffer_unref (buf);
- res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
- if (res != GST_FLOW_OK)
- goto pull_failed;
- else if (GST_BUFFER_SIZE (buf) < 8)
- goto too_small;
- tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
- }
-
- if (tag != GST_RIFF_TAG_idx1)
- goto no_index;
- if (!size)
- goto zero_index;
-
- gst_buffer_unref (buf);
-
- GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
-
- /* read chunk, advance offset */
- if (gst_riff_read_chunk (GST_ELEMENT_CAST (avi),
- avi->sinkpad, &offset, &tag, &buf) != GST_FLOW_OK)
- return;
-
- GST_INFO ("will parse index chunk size %u for tag %"
- GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
-
- gst_avi_demux_parse_index (avi, buf, index);
- if (*index)
- *alloc_list = g_list_append (*alloc_list, (*index)->data);
-
- /* debug our indexes */
- for (i = 0; i < avi->num_streams; i++) {
- avi_stream_context *stream;
-
- stream = &avi->stream[i];
- GST_DEBUG_OBJECT (avi, "stream %u: %u frames, %" G_GINT64_FORMAT " bytes",
- i, stream->total_frames, stream->total_bytes);
- }
- return;
-
- /* ERRORS */
-pull_failed:
- {
- GST_DEBUG_OBJECT (avi,
- "pull range failed: pos=%" G_GUINT64_FORMAT " size=8", offset);
- return;
- }
-too_small:
- {
- GST_DEBUG_OBJECT (avi, "Buffer is too small");
- gst_buffer_unref (buf);
- return;
- }
-no_index:
- {
- GST_WARNING_OBJECT (avi,
- "No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (tag));
- gst_buffer_unref (buf);
- return;
- }
-zero_index:
- {
- GST_WARNING_OBJECT (avi, "Empty index data (idx1) after movi chunk");
- gst_buffer_unref (buf);
- return;
- }
-}
-
-#if 0
-/*
- * Sync to next data chunk.
- */
-static gboolean
-gst_avi_demux_skip (GstAviDemux * avi, gboolean prevent_eos)
-{
- GstRiffRead *riff = GST_RIFF_READ (avi);
-
- if (prevent_eos) {
- guint64 pos, length;
- guint size;
- guint8 *data;
-
- pos = gst_bytestream_tell (riff->bs);
- length = gst_bytestream_length (riff->bs);
-
- if (pos + 8 > length)
- return FALSE;
-
- if (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8)
- return FALSE;
-
- size = GST_READ_UINT32_LE (&data[4]);
- if (size & 1)
- size++;
-
- /* Note, we're going to skip which might involve seeks. Therefore,
- * we need 1 byte more! */
- if (pos + 8 + size >= length)
- return FALSE;
- }
-
- return gst_riff_read_skip (riff);
-}
-
-static gboolean
-gst_avi_demux_sync (GstAviDemux * avi, guint32 * ret_tag, gboolean prevent_eos)
-{
- GstRiffRead *riff = GST_RIFF_READ (avi);
- guint32 tag;
- guint64 length = gst_bytestream_length (riff->bs);
-
- if (prevent_eos && gst_bytestream_tell (riff->bs) + 12 >= length)
- return FALSE;
-
- /* peek first (for the end of this 'list/movi' section) */
- if (!(tag = gst_riff_peek_tag (riff, &avi->level_up)))
- return FALSE;
-
- /* if we're at top-level, we didn't read the 'movi'
- * list tag yet. This can also be 'AVIX' in case of
- * openDML-2.0 AVI files. Lastly, it might be idx1,
- * in which case we skip it so we come at EOS. */
- while (1) {
- if (prevent_eos && gst_bytestream_tell (riff->bs) + 12 >= length)
- return FALSE;
-
- if (!(tag = gst_riff_peek_tag (riff, NULL)))
- return FALSE;
-
- switch (tag) {
- case GST_RIFF_TAG_LIST:
- if (!(tag = gst_riff_peek_list (riff)))
- return FALSE;
-
- switch (tag) {
- case GST_RIFF_LIST_AVIX:
- if (!gst_riff_read_list (riff, &tag))
- return FALSE;
- break;
-
- case GST_RIFF_LIST_movi:
- if (!gst_riff_read_list (riff, &tag))
- return FALSE;
- /* fall-through */
-
- case GST_RIFF_rec:
- goto done;
-
- default:
- GST_WARNING ("Unknown list %" GST_FOURCC_FORMAT " before AVI data",
- GST_FOURCC_ARGS (tag));
- /* fall-through */
-
- case GST_RIFF_TAG_JUNK:
- if (!gst_avi_demux_skip (avi, prevent_eos))
- return FALSE;
- break;
- }
- break;
-
- default:
- if ((tag & 0xff) >= '0' && (tag & 0xff) <= '9' &&
- ((tag >> 8) & 0xff) >= '0' && ((tag >> 8) & 0xff) <= '9') {
- goto done;
- }
- /* pass-through */
-
- case GST_RIFF_TAG_idx1:
- case GST_RIFF_TAG_JUNK:
- if (!gst_avi_demux_skip (avi, prevent_eos)) {
- return FALSE;
- }
- break;
- }
- }
-done:
- /* And then, we get the data */
- if (prevent_eos && gst_bytestream_tell (riff->bs) + 12 >= length)
- return FALSE;
-
- if (!(tag = gst_riff_peek_tag (riff, NULL)))
- return FALSE;
-
- /* Support for rec-list files */
- switch (tag) {
- case GST_RIFF_TAG_LIST:
- if (!(tag = gst_riff_peek_list (riff)))
- return FALSE;
- if (tag == GST_RIFF_rec) {
- /* Simply skip the list */
- if (!gst_riff_read_list (riff, &tag))
- return FALSE;
- if (!(tag = gst_riff_peek_tag (riff, NULL)))
- return FALSE;
- }
- break;
-
- case GST_RIFF_TAG_JUNK:
- gst_avi_demux_skip (avi, prevent_eos);
- return FALSE;
- }
-
- if (ret_tag)
- *ret_tag = tag;
-
- return TRUE;
-}
-#endif
-
-/*
- * gst_avi_demux_peek_tag:
- *
- * Returns the tag and size of the next chunk
- */
-static GstFlowReturn
-gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
- guint * size)
-{
- GstFlowReturn res = GST_FLOW_OK;
- GstBuffer *buf = NULL;
- guint bufsize;
-
- res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
- if (res != GST_FLOW_OK)
- goto pull_failed;
-
- bufsize = GST_BUFFER_SIZE (buf);
- if (bufsize != 8)
- goto wrong_size;
-
- *tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- *size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
-
- GST_LOG_OBJECT (avi, "Tag[%" GST_FOURCC_FORMAT "] (size:%d) %"
- G_GINT64_FORMAT " -- %" G_GINT64_FORMAT, GST_FOURCC_ARGS (*tag),
- *size, offset + 8, offset + 8 + (gint64) * size);
-done:
- gst_buffer_unref (buf);
-
- return res;
-
- /* ERRORS */
-pull_failed:
- {
- GST_DEBUG_OBJECT (avi, "pull_ranged returned %s", gst_flow_get_name (res));
- return res;
- }
-wrong_size:
- {
- GST_DEBUG_OBJECT (avi, "got %d bytes which is <> 8 bytes", bufsize);
- res = GST_FLOW_ERROR;
- goto done;
- }
-}
-
-/*
- * gst_avi_demux_next_data_buffer:
- *
- * Returns the offset and size of the next buffer
- * Position is the position of the buffer (after tag and size)
- */
-static GstFlowReturn
-gst_avi_demux_next_data_buffer (GstAviDemux * avi, guint64 * offset,
- guint32 * tag, guint * size)
-{
- guint64 off = *offset;
- guint _size = 0;
- GstFlowReturn res;
-
- do {
- res = gst_avi_demux_peek_tag (avi, off, tag, &_size);
- if (res != GST_FLOW_OK)
- break;
- if (*tag == GST_RIFF_TAG_LIST || *tag == GST_RIFF_TAG_RIFF)
- off += 8 + 4; /* skip tag + size + subtag */
- else {
- *offset = off + 8;
- *size = _size;
- break;
- }
- } while (TRUE);
-
- return res;
-}
-
-/*
- * gst_avi_demux_stream_scan:
- * @avi: calling element (used for debugging/errors).
- * @index: list of index entries, returned by this function.
- * @alloc_list: list of allocated data, returned by this function.
- *
- * Scan the file for all chunks to "create" a new index.
- * Return value indicates if we can continue reading the stream. It
- * does not say anything about whether we created an index.
- *
- * pull-range based
- */
-static gboolean
-gst_avi_demux_stream_scan (GstAviDemux * avi,
- GList ** index, GList ** alloc_list)
-{
- GstFlowReturn res;
- gst_avi_index_entry *entry, *entries = NULL;
- avi_stream_context *stream;
- GstFormat format;
- guint64 pos = avi->offset;
- guint64 length;
- gint64 tmplength;
- guint32 tag = 0;
- GList *list = NULL;
- guint index_size = 0;
-
- /* FIXME:
- * - implement non-seekable source support.
- */
- GST_DEBUG_OBJECT (avi,
- "Creating index %s existing index, starting at offset %" G_GUINT64_FORMAT,
- ((*index) ? "with" : "without"), pos);
-
- format = GST_FORMAT_BYTES;
- if (!gst_pad_query_peer_duration (avi->sinkpad, &format, &tmplength))
- return FALSE;
-
- length = tmplength;
-
- if (*index) {
- entry = g_list_last (*index)->data;
- pos = entry->offset + avi->index_offset + entry->size;
- if (entry->size & 1)
- pos++;
-
- if (pos >= length) {
- GST_LOG_OBJECT (avi, "Complete index, we're done");
- return TRUE;
- }
-
- GST_LOG_OBJECT (avi, "Incomplete index, seeking to last valid entry @ %"
- G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT " (%"
- G_GUINT64_FORMAT "+%u)", pos, length, entry->offset, entry->size);
- }
-
- while (TRUE) {
- guint stream_nr;
- guint size = 0;
-
- res = gst_avi_demux_next_data_buffer (avi, &pos, &tag, &size);
- if (G_UNLIKELY (res != GST_FLOW_OK))
- break;
-
- /* check valid stream */
- stream_nr = CHUNKID_TO_STREAMNR (tag);
- if (G_UNLIKELY (stream_nr >= avi->num_streams)) {
- GST_WARNING_OBJECT (avi,
- "Index entry has invalid stream nr %d", stream_nr);
- goto next;
- }
-
- stream = &avi->stream[stream_nr];
- if (G_UNLIKELY (stream->pad == NULL)) {
- GST_WARNING_OBJECT (avi,
- "Stream %d does not have an output pad, can't create new index",
- stream_nr);
- goto next;
- }
-
- /* pre-allocate */
- if (G_UNLIKELY (index_size % 1024 == 0)) {
- entries = g_new (gst_avi_index_entry, 1024);
- *alloc_list = g_list_prepend (*alloc_list, entries);
- }
- entry = &entries[index_size % 1024];
-
- entry->index_nr = index_size++;
- entry->stream_nr = stream_nr;
- entry->flags = GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME;
- entry->offset = pos - avi->index_offset;
- entry->size = size;
-
- /* timestamps, get timestamps of two consecutive frames to calculate
- * timestamp and duration. */
- format = GST_FORMAT_TIME;
- if (stream->is_vbr) {
- /* VBR stream */
- entry->ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames);
- entry->dur = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames + 1);
- } else {
- /* constant rate stream */
- entry->ts = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes);
- entry->dur = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes + entry->size);
- }
- entry->dur -= entry->ts;
-
- /* stream position */
- entry->bytes_before = stream->total_bytes;
- stream->total_bytes += entry->size;
- entry->frames_before = stream->total_frames;
- stream->total_frames++;
- stream->idx_duration = entry->ts + entry->dur;
-
- list = g_list_prepend (list, entry);
- GST_DEBUG_OBJECT (avi, "Added index entry %d (in stream: %d), offset %"
- G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT " for stream %d",
- index_size - 1, entry->frames_before, entry->offset,
- GST_TIME_ARGS (entry->ts), entry->stream_nr);
-
- next:
- /* update position */
- pos += GST_ROUND_UP_2 (size);
- if (G_UNLIKELY (pos > length)) {
- GST_WARNING_OBJECT (avi,
- "Stopping index lookup since we are further than EOF");
- break;
- }
- }
-
- /* FIXME: why is this disabled */
-#if 0
- while (gst_avi_demux_sync (avi, &tag, TRUE)) {
- guint stream_nr = CHUNKID_TO_STREAMNR (tag);
- guint8 *data;
- GstFormat format = GST_FORMAT_TIME;
-
- if (stream_nr >= avi->num_streams)
- goto next;
- stream = &avi->stream[stream_nr];
-
- /* get chunk size */
- if (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8)
- goto next;
-
- /* fill in */
- entry->index_nr = index_size++;
- entry->stream_nr = stream_nr;
- entry->flags = GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME;
- entry->offset = gst_bytestream_tell (riff->bs) + 8 - avi->index_offset;
- entry->size = GST_READ_UINT32_LE (&data[4]);
-
- /* timestamps */
- if (stream->is_vbr) {
- /* VBR stream */
- entry->ts = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames);
- entry->dur = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->total_frames + 1);
- } else {
- /* constant rate stream */
- entry->ts = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes);
- entry->dur = avi_stream_convert_bytes_to_time_unchecked (stream,
- stream->total_bytes + entry->size);
- }
- entry->dur -= entry->ts;
-
- /* stream position */
- entry->bytes_before = stream->total_bytes;
- stream->total_bytes += entry->size;
- entry->frames_before = stream->total_frames;
- stream->total_frames++;
-
- list = g_list_prepend (list, entry);
- GST_DEBUG_OBJECT (avi, "Added index entry %d (in stream: %d), offset %"
- G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT " for stream %d",
- index_size - 1, entry->frames_before, entry->offset,
- GST_TIME_ARGS (entry->ts), entry->stream_nr);
-
- next:
- if (!gst_avi_demux_skip (avi, TRUE))
- break;
- }
- /* seek back */
- if (!(event = gst_riff_read_seek (riff, pos))) {
- g_list_free (list);
- return FALSE;
- }
- gst_event_unref (event);
-
-#endif
-
- GST_DEBUG_OBJECT (avi, "index created, %d items", index_size);
-
- *index = g_list_concat (*index, g_list_reverse (list));
-
- return TRUE;
-}
-
-/*
- * gst_avi_demux_massage_index:
- * @avi: calling element (used for debugging/errors).
- *
- * We're going to go over each entry in the index and finetune
- * some things we don't like about AVI. For example, a single
- * chunk might be too long. Also, individual streams might be
- * out-of-sync. In the first case, we cut the chunk in several
- * smaller pieces. In the second case, we re-order chunk reading
- * order. The end result should be a smoother playing AVI.
- */
-static gboolean
-gst_avi_demux_massage_index (GstAviDemux * avi,
- GList * list, GList * alloc_list)
-{
- gst_avi_index_entry *entry;
- avi_stream_context *stream;
- guint i;
- GList *node;
- gint64 delay = G_GINT64_CONSTANT (0);
-
- GST_LOG_OBJECT (avi, "Starting index massage, nr_entries = %d",
- list ? g_list_length (list) : 0);
-
- if (list) {
-#ifndef GST_DISABLE_GST_DEBUG
- guint num_added_total = 0;
- guint num_per_stream[GST_AVI_DEMUX_MAX_STREAMS] = { 0, };
-#endif
- GST_LOG_OBJECT (avi,
- "I'm now going to cut large chunks into smaller pieces");
-
- /* cut chunks in small (seekable) pieces
- * FIXME: this should be a property where a value of
- * GST_CLOCK_TIME_NONE would disable the chunking
- */
-#define MAX_DURATION (GST_SECOND / 2)
- for (i = 0; i < avi->num_streams; i++) {
- /* only chop streams that have exactly *one* chunk */
- if (avi->stream[i].total_frames != 1)
- continue;
-
- for (node = list; node != NULL; node = node->next) {
- entry = node->data;
-
- if (entry->stream_nr != i)
- continue;
-
- /* check for max duration of a single buffer. I suppose that
- * the allocation of index entries could be improved. */
- stream = &avi->stream[entry->stream_nr];
- if (entry->dur > MAX_DURATION
- && stream->strh->type == GST_RIFF_FCC_auds) {
- guint32 ideal_size;
- gst_avi_index_entry *entries;
- guint old_size, num_added;
- GList *node2;
-
- /* cut in 1/10th of a second */
- ideal_size = stream->strf.auds->av_bps / 10;
-
- /* ensure chunk size is multiple of blockalign */
- if (stream->strf.auds->blockalign > 1)
- ideal_size -= ideal_size % stream->strf.auds->blockalign;
-
- /* copy index */
- old_size = entry->size;
- num_added = (entry->size - 1) / ideal_size;
- avi->index_size += num_added;
- entries = g_malloc (sizeof (gst_avi_index_entry) * num_added);
- alloc_list = g_list_prepend (alloc_list, entries);
- for (node2 = node->next; node2 != NULL; node2 = node2->next) {
- gst_avi_index_entry *entry2 = node2->data;
-
- entry2->index_nr += num_added;
- if (entry2->stream_nr == entry->stream_nr)
- entry2->frames_before += num_added;
- }
-
- /* new sized index chunks */
- for (i = 0; i < num_added + 1; i++) {
- gst_avi_index_entry *entry2;
-
- if (i == 0) {
- entry2 = entry;
- } else {
- entry2 = &entries[i - 1];
- list = g_list_insert_before (list, node->next, entry2);
- entry = node->data;
- node = node->next;
- memcpy (entry2, entry, sizeof (gst_avi_index_entry));
- }
-
- if (old_size >= ideal_size) {
- entry2->size = ideal_size;
- old_size -= ideal_size;
- } else {
- entry2->size = old_size;
- }
-
- entry2->dur = GST_SECOND * entry2->size / stream->strf.auds->av_bps;
- if (i != 0) {
- entry2->index_nr++;
- entry2->ts += entry->dur;
- entry2->offset += entry->size;
- entry2->bytes_before += entry->size;
- entry2->frames_before++;
- }
- }
-#ifndef GST_DISABLE_GST_DEBUG
- num_added_total += num_added;
-#endif
- }
- }
- }
-#ifndef GST_DISABLE_GST_DEBUG
- if (num_added_total)
- GST_LOG ("added %u new index entries", num_added_total);
-#endif
-
- GST_LOG_OBJECT (avi, "I'm now going to reorder the index entries for time");
-
- /* re-order for time */
- list = g_list_sort (list, (GCompareFunc) sort);
-
- /* make a continous array out of the list */
- avi->index_size = g_list_length (list);
- avi->index_entries = g_try_new (gst_avi_index_entry, avi->index_size);
- if (!avi->index_entries)
- goto out_of_mem;
-
- entry = (gst_avi_index_entry *) (list->data);
- delay = entry->ts;
-
- GST_LOG_OBJECT (avi,
- "Building index array, nr_entries = %d (time offset = %"
- GST_TIME_FORMAT, avi->index_size, GST_TIME_ARGS (delay));
-
- for (i = 0, node = list; node != NULL; node = node->next, i++) {
- entry = node->data;
- entry->index_nr = i;
- entry->ts -= delay;
- memcpy (&avi->index_entries[i], entry, sizeof (gst_avi_index_entry));
-#ifndef GST_DISABLE_GST_DEBUG
- num_per_stream[entry->stream_nr]++;
-#endif
-
- GST_LOG_OBJECT (avi, "Sorted index entry %3d for stream %d of size %6u"
- " at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
- " dur %" GST_TIME_FORMAT,
- avi->index_entries[i].index_nr, entry->stream_nr, entry->size,
- entry->offset, GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (entry->dur));
- }
- if (delay) {
- for (i = 0; i < avi->num_streams; i++) {
- stream = &avi->stream[i];
- stream->idx_duration -= delay;
- }
- }
-#ifndef GST_DISABLE_GST_DEBUG
- {
- gchar str[GST_AVI_DEMUX_MAX_STREAMS * (1 + 6 + 2)];
- gchar *pad_name;
-
- for (i = 0; i < avi->num_streams; i++) {
- if (!avi->stream[i].pad)
- continue;
- pad_name = GST_OBJECT_NAME (avi->stream[i].pad);
- sprintf (&str[i * (1 + 6 + 2)], " %6u %c", num_per_stream[i],
- pad_name[0]);
- }
- GST_LOG_OBJECT (avi, "indizies per stream:%20s", str);
- }
-#endif
-
- GST_LOG_OBJECT (avi, "Freeing original index list");
- /* all the node->data in list point to alloc_list chunks */
-
- g_list_free (list);
- }
- if (alloc_list) {
- g_list_foreach (alloc_list, (GFunc) g_free, NULL);
- g_list_free (alloc_list);
- }
-#ifndef GST_DISABLE_GST_DEBUG
- for (i = 0; i < avi->num_streams; i++) {
- GST_LOG_OBJECT (avi, "Stream %d, %d frames, %8" G_GUINT64_FORMAT " bytes",
- i, avi->stream[i].total_frames, avi->stream[i].total_bytes);
- }
-#endif
-
- GST_LOG_OBJECT (avi, "Index massaging done");
- return TRUE;
-
- /* ERRORS */
-out_of_mem:
- GST_WARNING_OBJECT (avi, "Out of memory for %" G_GSIZE_FORMAT " bytes",
- sizeof (gst_avi_index_entry) * avi->index_size);
- return FALSE;
-}
-
-static void
-gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
-{
- gint stream;
- GstClockTime total;
-
- total = GST_CLOCK_TIME_NONE;
-
- /* all streams start at a timestamp 0 */
- for (stream = 0; stream < avi->num_streams; stream++) {
- GstClockTime duration, hduration;
- avi_stream_context *streamc = &avi->stream[stream];
- gst_riff_strh *strh = streamc->strh;
-
- if (!strh)
- continue;
-
- /* get header duration for the stream */
- hduration = streamc->hdr_duration;
-
- /* index duration calculated during parsing, invariant under massage */
- duration = streamc->idx_duration;
-
- /* now pick a good duration */
- if (GST_CLOCK_TIME_IS_VALID (duration)) {
- /* index gave valid duration, use that */
- GST_INFO ("Stream %d duration according to index: %" GST_TIME_FORMAT,
- stream, GST_TIME_ARGS (duration));
- } else {
- /* fall back to header info to calculate a duration */
- duration = hduration;
- }
- /* set duration for the stream */
- streamc->duration = duration;
-
- /* find total duration */
- if (total == GST_CLOCK_TIME_NONE || duration > total)
- total = duration;
- }
-
- if (GST_CLOCK_TIME_IS_VALID (total) && (total > 0)) {
- /* now update the duration for those streams where we had none */
- for (stream = 0; stream < avi->num_streams; stream++) {
- avi_stream_context *streamc = &avi->stream[stream];
-
- if (!GST_CLOCK_TIME_IS_VALID (streamc->duration)
- || streamc->duration == 0) {
- streamc->duration = total;
-
- GST_INFO ("Stream %d duration according to total: %" GST_TIME_FORMAT,
- stream, GST_TIME_ARGS (total));
- }
- }
- }
-
- /* and set the total duration in the segment. */
- GST_INFO ("Setting total duration to: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (total));
-
- gst_segment_set_duration (&avi->segment, GST_FORMAT_TIME, total);
-}
-
-/* returns FALSE if there are no pads to deliver event to,
- * otherwise TRUE (whatever the outcome of event sending) */
-static gboolean
-gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event)
-{
- gboolean result = FALSE;
- gint i;
-
- GST_DEBUG_OBJECT (avi, "sending %s event to %d streams",
- GST_EVENT_TYPE_NAME (event), avi->num_streams);
-
- if (avi->num_streams) {
- for (i = 0; i < avi->num_streams; i++) {
- avi_stream_context *stream = &avi->stream[i];
-
- if (stream->pad) {
- result = TRUE;
- gst_pad_push_event (stream->pad, gst_event_ref (event));
- }
- }
- }
- gst_event_unref (event);
- return result;
-}
-
-/*
- * Read AVI headers when streaming
- */
-static GstFlowReturn
-gst_avi_demux_stream_header_push (GstAviDemux * avi)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- guint32 tag = 0;
- guint32 ltag = 0;
- guint32 size = 0;
- const guint8 *data;
- GstBuffer *buf = NULL, *sub = NULL;
- guint offset = 4;
- gint64 stop;
-
- GST_DEBUG ("Reading and parsing avi headers: %d", avi->header_state);
-
- switch (avi->header_state) {
- case GST_AVI_DEMUX_HEADER_TAG_LIST:
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- avi->offset += 8 + ((size + 1) & ~1);
- if (tag != GST_RIFF_TAG_LIST)
- goto header_no_list;
-
- gst_adapter_flush (avi->adapter, 8);
- /* Find the 'hdrl' LIST tag */
- GST_DEBUG ("Reading %d bytes", size);
- buf = gst_adapter_take_buffer (avi->adapter, size);
-
- if (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl)
- goto header_no_hdrl;
-
- /* mind padding */
- if (size & 1)
- gst_adapter_flush (avi->adapter, 1);
-
- GST_DEBUG ("'hdrl' LIST tag found. Parsing next chunk");
-
- /* the hdrl starts with a 'avih' header */
- if (!gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub))
- goto header_no_avih;
-
- if (tag != GST_RIFF_TAG_avih)
- goto header_no_avih;
-
- if (!gst_avi_demux_parse_avih (GST_ELEMENT (avi), sub, &avi->avih))
- goto header_wrong_avih;
-
- GST_DEBUG_OBJECT (avi, "AVI header ok, reading elemnts from header");
-
- /* now, read the elements from the header until the end */
- while (gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag,
- &sub)) {
- /* sub can be NULL on empty tags */
- if (!sub)
- continue;
-
- switch (tag) {
- case GST_RIFF_TAG_LIST:
- if (GST_BUFFER_SIZE (sub) < 4)
- goto next;
-
- switch (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))) {
- case GST_RIFF_LIST_strl:
- if (!(gst_avi_demux_parse_stream (avi, sub))) {
- sub = NULL;
- GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
- ("failed to parse stream, ignoring"));
- goto next;
- }
- sub = NULL;
- goto next;
- case GST_RIFF_LIST_odml:
- gst_avi_demux_parse_odml (avi, sub);
- sub = NULL;
- break;
- default:
- GST_WARNING_OBJECT (avi,
- "Unknown list %" GST_FOURCC_FORMAT " in AVI header",
- GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA
- (sub))));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- goto next;
- }
- break;
- default:
- GST_WARNING_OBJECT (avi,
- "Unknown off %d tag %" GST_FOURCC_FORMAT " in AVI header",
- offset, GST_FOURCC_ARGS (tag));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- next:
- /* move to next chunk */
- if (sub)
- gst_buffer_unref (sub);
- sub = NULL;
- break;
- }
- }
- gst_buffer_unref (buf);
- GST_DEBUG ("elements parsed");
-
- /* check parsed streams */
- if (avi->num_streams == 0) {
- goto no_streams;
- } else if (avi->num_streams != avi->avih->streams) {
- GST_WARNING_OBJECT (avi,
- "Stream header mentioned %d streams, but %d available",
- avi->avih->streams, avi->num_streams);
- }
- GST_DEBUG ("Get junk and info next");
- avi->header_state = GST_AVI_DEMUX_HEADER_INFO;
- } else {
- /* Need more data */
- return ret;
- }
- /* fall-though */
- case GST_AVI_DEMUX_HEADER_INFO:
- GST_DEBUG_OBJECT (avi, "skipping junk between header and data ...");
- while (TRUE) {
- if (gst_adapter_available (avi->adapter) < 12)
- return GST_FLOW_OK;
-
- data = gst_adapter_peek (avi->adapter, 12);
- tag = GST_READ_UINT32_LE (data);
- size = GST_READ_UINT32_LE (data + 4);
- ltag = GST_READ_UINT32_LE (data + 8);
-
- if (tag == GST_RIFF_TAG_LIST) {
- switch (ltag) {
- case GST_RIFF_LIST_movi:
- gst_adapter_flush (avi->adapter, 12);
- avi->offset += 12;
- goto skipping_done;
- case GST_RIFF_LIST_INFO:
- GST_DEBUG ("Found INFO chunk");
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- GST_DEBUG ("got size %d", size);
- avi->offset += 12;
- gst_adapter_flush (avi->adapter, 12);
- if (size > 4) {
- buf = gst_adapter_take_buffer (avi->adapter, size - 4);
- /* mind padding */
- if (size & 1)
- gst_adapter_flush (avi->adapter, 1);
- gst_riff_parse_info (GST_ELEMENT (avi), buf,
- &avi->globaltags);
- gst_buffer_unref (buf);
-
- avi->offset += ((size + 1) & ~1) - 4;
- } else {
- GST_DEBUG ("skipping INFO LIST prefix");
- }
- } else {
- /* Need more data */
- return GST_FLOW_OK;
- }
- break;
- default:
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- avi->offset += 8 + ((size + 1) & ~1);
- gst_adapter_flush (avi->adapter, 8 + ((size + 1) & ~1));
- // ??? goto iterate; ???
- } else {
- /* Need more data */
- return GST_FLOW_OK;
- }
- break;
- }
- } else {
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- avi->offset += 8 + ((size + 1) & ~1);
- gst_adapter_flush (avi->adapter, 8 + ((size + 1) & ~1));
- //goto iterate;
- } else {
- /* Need more data */
- return GST_FLOW_OK;
- }
- }
- }
- break;
- default:
- GST_WARNING ("unhandled header state: %d", avi->header_state);
- break;
- }
-skipping_done:
-
- GST_DEBUG_OBJECT (avi, "skipping done ... (streams=%u, stream[0].indexes=%p)",
- avi->num_streams, avi->stream[0].indexes);
-
- GST_DEBUG ("Found movi chunk. Starting to stream data");
- avi->state = GST_AVI_DEMUX_MOVI;
-
-#if 0
- /*GList *index = NULL, *alloc = NULL; */
-
- /* ######################## this need to be integrated with the state */
- /* create or read stream index (for seeking) */
- if (avi->stream[0].indexes != NULL) {
- gst_avi_demux_read_subindexes_push (avi, &index, &alloc);
- }
- if (!index) {
- if (avi->avih->flags & GST_RIFF_AVIH_HASINDEX) {
- gst_avi_demux_stream_index (avi, &index, &alloc);
- }
- /* some indexes are incomplete, continue streaming from there */
- if (!index)
- gst_avi_demux_stream_scan (avi, &index, &alloc);
- }
-
- /* this is a fatal error */
- if (!index)
- goto no_index;
-
- if (!gst_avi_demux_massage_index (avi, index, alloc))
- goto no_index;
-
- gst_avi_demux_calculate_durations_from_index (avi);
- /* ######################## */
-#endif
-
- /* create initial NEWSEGMENT event */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
- GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
- if (avi->seek_event)
- gst_event_unref (avi->seek_event);
- avi->seek_event = gst_event_new_new_segment
- (FALSE, avi->segment.rate, GST_FORMAT_TIME,
- avi->segment.start, stop, avi->segment.start);
-
- /* at this point we know all the streams and we can signal the no more
- * pads signal */
- GST_DEBUG_OBJECT (avi, "signaling no more pads");
- gst_element_no_more_pads (GST_ELEMENT (avi));
-
- return GST_FLOW_OK;
-
- /* ERRORS */
-no_streams:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No streams found"));
- return GST_FLOW_ERROR;
- }
-header_no_list:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no LIST at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- return GST_FLOW_ERROR;
- }
-header_no_hdrl:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no hdrl at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-header_no_avih:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no avih at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- if (sub)
- gst_buffer_unref (sub);
-
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-header_wrong_avih:
- {
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-}
-
-/*
- * Read full AVI headers.
- */
-static GstFlowReturn
-gst_avi_demux_stream_header_pull (GstAviDemux * avi)
-{
- GstFlowReturn res;
- GstBuffer *buf, *sub = NULL;
- guint32 tag;
- GList *index = NULL, *alloc = NULL;
- guint offset = 4;
- gint64 stop;
- GstElement *element = GST_ELEMENT_CAST (avi);
-
- /* the header consists of a 'hdrl' LIST tag */
- res = gst_riff_read_chunk (element, avi->sinkpad, &avi->offset, &tag, &buf);
- if (res != GST_FLOW_OK)
- goto pull_range_failed;
- else if (tag != GST_RIFF_TAG_LIST)
- goto no_list;
- else if (GST_BUFFER_SIZE (buf) < 4)
- goto no_header;
-
- GST_DEBUG_OBJECT (avi, "parsing headers");
-
- /* Find the 'hdrl' LIST tag */
- while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl) {
- GST_LOG_OBJECT (avi, "buffer contains %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf))));
-
- /* Eat up */
- gst_buffer_unref (buf);
-
- /* read new chunk */
- res = gst_riff_read_chunk (element, avi->sinkpad, &avi->offset, &tag, &buf);
- if (res != GST_FLOW_OK)
- goto pull_range_failed;
- else if (tag != GST_RIFF_TAG_LIST)
- goto no_list;
- else if (GST_BUFFER_SIZE (buf) < 4)
- goto no_header;
- }
-
- GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
-
- /* the hdrl starts with a 'avih' header */
- if (!gst_riff_parse_chunk (element, buf, &offset, &tag, &sub))
- goto no_avih;
- else if (tag != GST_RIFF_TAG_avih)
- goto no_avih;
- else if (!gst_avi_demux_parse_avih (element, sub, &avi->avih))
- goto invalid_avih;
-
- GST_DEBUG_OBJECT (avi, "AVI header ok, reading elements from header");
-
- /* now, read the elements from the header until the end */
- while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
- /* sub can be NULL on empty tags */
- if (!sub)
- continue;
-
- switch (tag) {
- case GST_RIFF_TAG_LIST:
- {
- guint8 *data;
- guint32 fourcc;
-
- if (GST_BUFFER_SIZE (sub) < 4)
- goto next;
-
- data = GST_BUFFER_DATA (sub);
- fourcc = GST_READ_UINT32_LE (data);
-
- switch (fourcc) {
- case GST_RIFF_LIST_strl:
- if (!(gst_avi_demux_parse_stream (avi, sub))) {
- GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
- ("failed to parse stream, ignoring"));
- sub = NULL;
- }
- sub = NULL;
- goto next;
- case GST_RIFF_LIST_odml:
- gst_avi_demux_parse_odml (avi, sub);
- sub = NULL;
- break;
- default:
- GST_WARNING_OBJECT (avi,
- "Unknown list %" GST_FOURCC_FORMAT " in AVI header",
- GST_FOURCC_ARGS (fourcc));
- GST_MEMDUMP_OBJECT (avi, "Unknown list", GST_BUFFER_DATA (sub),
- GST_BUFFER_SIZE (sub));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- goto next;
- }
- break;
- }
- default:
- GST_WARNING_OBJECT (avi,
- "Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
- GST_FOURCC_ARGS (tag), offset);
- GST_MEMDUMP_OBJECT (avi, "Unknown tag", GST_BUFFER_DATA (sub),
- GST_BUFFER_SIZE (sub));
- /* fall-through */
- case GST_RIFF_TAG_JUNK:
- next:
- if (sub)
- gst_buffer_unref (sub);
- sub = NULL;
- break;
- }
- }
- gst_buffer_unref (buf);
- GST_DEBUG ("elements parsed");
-
- /* check parsed streams */
- if (avi->num_streams == 0)
- goto no_streams;
- else if (avi->num_streams != avi->avih->streams) {
- GST_WARNING_OBJECT (avi,
- "Stream header mentioned %d streams, but %d available",
- avi->avih->streams, avi->num_streams);
- }
-
- GST_DEBUG_OBJECT (avi, "skipping junk between header and data, offset=%"
- G_GUINT64_FORMAT, avi->offset);
-
- /* Now, find the data (i.e. skip all junk between header and data) */
- do {
- guint size;
- guint32 tag, ltag;
-
- res = gst_pad_pull_range (avi->sinkpad, avi->offset, 12, &buf);
- if (res != GST_FLOW_OK) {
- GST_DEBUG_OBJECT (avi, "pull_range failure while looking for tags");
- goto pull_range_failed;
- } else if (GST_BUFFER_SIZE (buf) < 12) {
- GST_DEBUG_OBJECT (avi, "got %d bytes which is less than 12 bytes",
- GST_BUFFER_SIZE (buf));
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-
- tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
- ltag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 8);
-
- GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
- GST_FOURCC_ARGS (tag), size);
- GST_MEMDUMP ("Tag content", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
- gst_buffer_unref (buf);
-
- switch (tag) {
- case GST_RIFF_TAG_LIST:{
- switch (ltag) {
- case GST_RIFF_LIST_movi:
- GST_DEBUG_OBJECT (avi,
- "Reached the 'movi' tag, we're done with skipping");
- goto skipping_done;
- case GST_RIFF_LIST_INFO:
- res =
- gst_riff_read_chunk (element, avi->sinkpad, &avi->offset, &tag,
- &buf);
- if (res != GST_FLOW_OK) {
- GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
- goto pull_range_failed;
- }
- GST_DEBUG ("got size %u", GST_BUFFER_SIZE (buf));
- if (size < 4) {
- GST_DEBUG ("skipping INFO LIST prefix");
- avi->offset += (4 - GST_ROUND_UP_2 (size));
- gst_buffer_unref (buf);
- continue;
- }
-
- sub = gst_buffer_create_sub (buf, 4, GST_BUFFER_SIZE (buf) - 4);
- gst_riff_parse_info (element, sub, &avi->globaltags);
- if (sub) {
- gst_buffer_unref (sub);
- sub = NULL;
- }
- gst_buffer_unref (buf);
- /* gst_riff_read_chunk() has already advanced avi->offset */
- break;
- default:
- GST_WARNING_OBJECT (avi,
- "Skipping unknown list tag %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (ltag));
- avi->offset += 8 + ((size + 1) & ~1);
- break;
- }
- }
- break;
- default:
- GST_WARNING_OBJECT (avi, "Skipping unknown tag %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (tag));
- /* Fall-through */
- case GST_MAKE_FOURCC ('J', 'U', 'N', 'Q'):
- case GST_MAKE_FOURCC ('J', 'U', 'N', 'K'):
- avi->offset += 8 + ((size + 1) & ~1);
- break;
- }
- } while (1);
-skipping_done:
-
- GST_DEBUG_OBJECT (avi, "skipping done ... (streams=%u, stream[0].indexes=%p)",
- avi->num_streams, avi->stream[0].indexes);
-
- /* create or read stream index (for seeking) */
- if (avi->stream[0].indexes != NULL) {
- /* we read a super index already (gst_avi_demux_parse_superindex() ) */
- gst_avi_demux_read_subindexes_pull (avi, &index, &alloc);
- }
- if (!index) {
- if (avi->avih->flags & GST_RIFF_AVIH_HASINDEX) {
- gst_avi_demux_stream_index (avi, &index, &alloc);
- }
- /* some indexes are incomplete, continue streaming from there */
- if (!index)
- gst_avi_demux_stream_scan (avi, &index, &alloc);
- }
-
- /* this is a fatal error */
- if (!index)
- goto no_index;
-
- if (!gst_avi_demux_massage_index (avi, index, alloc))
- goto no_index;
-
- gst_avi_demux_calculate_durations_from_index (avi);
-
- /* create initial NEWSEGMENT event */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
- GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
- if (avi->seek_event)
- gst_event_unref (avi->seek_event);
- avi->seek_event = gst_event_new_new_segment
- (FALSE, avi->segment.rate, GST_FORMAT_TIME,
- avi->segment.start, stop, avi->segment.start);
-
- /* at this point we know all the streams and we can signal the no more
- * pads signal */
- GST_DEBUG_OBJECT (avi, "signaling no more pads");
- gst_element_no_more_pads (GST_ELEMENT_CAST (avi));
-
- return GST_FLOW_OK;
-
- /* ERRORS */
-no_list:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no LIST at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-no_header:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no hdrl at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-no_avih:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (no avih at start): %"
- GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
- if (sub)
- gst_buffer_unref (sub);
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-invalid_avih:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Invalid AVI header (cannot parse avih at start)"));
- gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
- }
-no_streams:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No streams found"));
- return GST_FLOW_ERROR;
- }
-no_index:
- {
- GST_WARNING ("file without or too big index");
- g_list_free (index);
- g_list_foreach (alloc, (GFunc) g_free, NULL);
- g_list_free (alloc);
-
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("Could not get/create index"));
- return GST_FLOW_ERROR;
- }
-pull_range_failed:
- {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
- ("pull_range flow reading header: %s", gst_flow_get_name (res)));
- return GST_FLOW_ERROR;
- }
-}
-
-/*
- * Do the actual seeking.
- */
-static gboolean
-gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
-{
- GstClockTime seek_time;
- gboolean keyframe;
- gst_avi_index_entry *entry, *kentry;
- gint old_entry;
-
- seek_time = segment->last_stop;
- keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
-
- /* FIXME: if we seek in an openDML file, we will have multiple
- * primary levels. Seeking in between those will cause havoc. */
-
- /* save old position so we can see if we must mark a discont. */
- old_entry = avi->current_entry;
-
- /* get the entry for the requested position, which is always in last_stop.
- * we search the index entry for stream 0, since all entries are sorted by
- * time and stream we automagically are positioned for the other streams as
- * well. FIXME, this code assumes the main stream with keyframes is stream 0,
- * which is mostly correct... */
- if (!(entry = gst_avi_demux_index_entry_for_time (avi, 0, seek_time)))
- goto no_entry;
-
- GST_DEBUG_OBJECT (avi,
- "Got requested entry %d [stream:%d / ts:%" GST_TIME_FORMAT
- " / duration:%" GST_TIME_FORMAT "]", entry->index_nr,
- entry->stream_nr, GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (entry->dur));
-
- /* check if we are already on a keyframe */
- if (!(entry->flags & GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME)) {
- /* now go to the previous keyframe, this is where we should start
- * decoding from. */
- if (!(kentry = gst_avi_demux_index_prev (avi, 0, entry->index_nr,
- GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME))) {
- goto no_entry;
- }
- } else {
- /* we were on a keyframe */
- kentry = entry;
- }
-
- GST_DEBUG_OBJECT (avi,
- "Got keyframe entry %d [stream:%d / ts:%" GST_TIME_FORMAT
- " / duration:%" GST_TIME_FORMAT "]", kentry->index_nr,
- entry->stream_nr, GST_TIME_ARGS (kentry->ts),
- GST_TIME_ARGS (kentry->dur));
-
- /* we must start decoding at the keyframe */
- avi->current_entry = kentry->index_nr;
-
- if (segment->rate < 0.0) {
- gst_avi_index_entry *next_keyframe;
-
- /* Because we don't know the frame order we need to push from the prev keyframe
- * to the next keyframe. If there is a smart decoder downstream he will notice
- * that there are too many encoded frames send and return UNEXPECTED when there
- * are enough decoded frames to fill the segment.
- */
- next_keyframe =
- gst_avi_demux_index_next (avi, 0, kentry->index_nr,
- GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME);
- if (!next_keyframe)
- next_keyframe = gst_avi_demux_index_last (avi, 0);
-
- avi->reverse_start_index = kentry->index_nr;
- avi->reverse_stop_index = next_keyframe->index_nr;
-
- GST_DEBUG_OBJECT (avi, "reverse seek: start idx (%d) and stop idx (%d)",
- avi->reverse_start_index, avi->reverse_stop_index);
- }
-
- if (keyframe) {
- /* when seeking to a keyframe, we update the result seek time
- * to the time of the keyframe. */
- seek_time = avi->index_entries[avi->current_entry].ts;
- }
-
-next:
- /* if we changed position, mark a DISCONT on all streams */
- if (avi->current_entry != old_entry) {
- gint i;
-
- for (i = 0; i < avi->num_streams; i++) {
- avi->stream[i].discont = TRUE;
- }
- }
-
- GST_DEBUG_OBJECT (avi, "seek: %" GST_TIME_FORMAT
- " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe);
-
- /* the seek time is also the last_stop and stream time */
- segment->last_stop = seek_time;
- segment->time = seek_time;
-
- return TRUE;
-
-no_entry:
- {
- /* we could not find an entry for the given time */
- GST_WARNING_OBJECT (avi,
- "Couldn't find AviIndexEntry for time:%" GST_TIME_FORMAT,
- GST_TIME_ARGS (seek_time));
- if (avi->current_entry >= avi->index_size && avi->index_size > 0)
- avi->current_entry = avi->index_size - 1;
-
- goto next;
- }
-}
-
-/*
- * Handle seek event.
- */
-static gboolean
-gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
-{
- gdouble rate;
- GstFormat format;
- GstSeekFlags flags;
- GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
- gint64 cur, stop;
- gboolean flush;
- gboolean update;
- GstSegment seeksegment = { 0, };
-
- if (event) {
- GST_DEBUG_OBJECT (avi, "doing seek with event");
-
- gst_event_parse_seek (event, &rate, &format, &flags,
- &cur_type, &cur, &stop_type, &stop);
-
- /* we have to have a format as the segment format. Try to convert
- * if not. */
- if (format != GST_FORMAT_TIME) {
- GstFormat fmt = GST_FORMAT_TIME;
- gboolean res = TRUE;
-
- if (cur_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, cur, &fmt, &cur);
- if (res && stop_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, stop, &fmt, &stop);
- if (!res)
- goto no_format;
-
- format = fmt;
- }
- GST_DEBUG_OBJECT (avi,
- "seek requested: rate %g cur %" GST_TIME_FORMAT " stop %"
- GST_TIME_FORMAT, rate, GST_TIME_ARGS (cur), GST_TIME_ARGS (stop));
- /* FIXME: can we do anything with rate!=1.0 */
- } else {
- GST_DEBUG_OBJECT (avi, "doing seek without event");
- flags = 0;
- rate = 1.0;
- }
-
- /* save flush flag */
- flush = flags & GST_SEEK_FLAG_FLUSH;
-
- if (flush) {
- GstEvent *event = gst_event_new_flush_start ();
-
- /* for a flushing seek, we send a flush_start on all pads. This will
- * eventually stop streaming with a WRONG_STATE. We can thus eventually
- * take the STREAM_LOCK. */
- GST_DEBUG_OBJECT (avi, "sending flush start");
- gst_avi_demux_push_event (avi, gst_event_ref (event));
- gst_pad_push_event (avi->sinkpad, event);
- } else {
- /* a non-flushing seek, we PAUSE the task so that we can take the
- * STREAM_LOCK */
- GST_DEBUG_OBJECT (avi, "non flushing seek, pausing task");
- gst_pad_pause_task (avi->sinkpad);
- }
-
- /* wait for streaming to stop */
- GST_DEBUG_OBJECT (avi, "wait for streaming to stop");
- GST_PAD_STREAM_LOCK (avi->sinkpad);
-
- /* copy segment, we need this because we still need the old
- * segment when we close the current segment. */
- memcpy (&seeksegment, &avi->segment, sizeof (GstSegment));
-
- if (event) {
- GST_DEBUG_OBJECT (avi, "configuring seek");
- gst_segment_set_seek (&seeksegment, rate, format, flags,
- cur_type, cur, stop_type, stop, &update);
- }
-
- /* do the seek, seeksegment.last_stop contains the new position, this
- * actually never fails. */
- gst_avi_demux_do_seek (avi, &seeksegment);
-
- if (flush) {
- gint i;
-
- GST_DEBUG_OBJECT (avi, "sending flush stop");
- gst_avi_demux_push_event (avi, gst_event_new_flush_stop ());
- gst_pad_push_event (avi->sinkpad, gst_event_new_flush_stop ());
- /* reset the last flow and mark discont, FLUSH is always DISCONT */
- for (i = 0; i < avi->num_streams; i++) {
- avi->stream[i].last_flow = GST_FLOW_OK;
- avi->stream[i].discont = TRUE;
- }
- } else if (avi->segment_running) {
- GstEvent *seg;
-
- /* we are running the current segment and doing a non-flushing seek,
- * close the segment first based on the last_stop. */
- GST_DEBUG_OBJECT (avi, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, avi->segment.start, avi->segment.last_stop);
- seg = gst_event_new_new_segment (TRUE,
- avi->segment.rate, avi->segment.format,
- avi->segment.start, avi->segment.last_stop, avi->segment.time);
- gst_avi_demux_push_event (avi, seg);
- }
-
- /* now update the real segment info */
- memcpy (&avi->segment, &seeksegment, sizeof (GstSegment));
-
- /* post the SEGMENT_START message when we do segmented playback */
- if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
- gst_element_post_message (GST_ELEMENT (avi),
- gst_message_new_segment_start (GST_OBJECT (avi),
- avi->segment.format, avi->segment.last_stop));
- }
-
- /* prepare for streaming again */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
- /* queue the segment event for the streaming thread. */
- if (avi->seek_event)
- gst_event_unref (avi->seek_event);
- if (avi->segment.rate > 0.0) {
- avi->seek_event = gst_event_new_new_segment (FALSE,
- avi->segment.rate, avi->segment.format,
- avi->segment.last_stop, stop, avi->segment.time);
- } else {
- avi->seek_event = gst_event_new_new_segment (FALSE,
- avi->segment.rate, avi->segment.format,
- avi->segment.start, avi->segment.last_stop, avi->segment.start);
- }
-
- if (!avi->streaming) {
- avi->segment_running = TRUE;
- gst_pad_start_task (avi->sinkpad, (GstTaskFunction) gst_avi_demux_loop,
- avi->sinkpad);
- }
- GST_PAD_STREAM_UNLOCK (avi->sinkpad);
-
- return TRUE;
-
- /* ERRORS */
-no_format:
- {
- GST_DEBUG_OBJECT (avi, "unsupported format given, seek aborted.");
- return FALSE;
- }
-}
-
-/*
- * Helper for gst_avi_demux_invert()
- */
-static inline void
-swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
-{
- memcpy (tmp, d1, bytes);
- memcpy (d1, d2, bytes);
- memcpy (d2, tmp, bytes);
-}
-
-
-#define gst_avi_demux_is_uncompressed(fourcc) \
- (fourcc == GST_RIFF_DIB || \
- fourcc == GST_RIFF_rgb || \
- fourcc == GST_RIFF_RGB || fourcc == GST_RIFF_RAW)
-
-/*
- * Invert DIB buffers... Takes existing buffer and
- * returns either the buffer or a new one (with old
- * one dereferenced).
- * FIXME: can't we preallocate tmp? and remember stride, bpp?
- */
-static GstBuffer *
-gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf)
-{
- GstStructure *s;
- gint y, w, h;
- gint bpp, stride;
- guint8 *tmp = NULL;
-
- if (stream->strh->type != GST_RIFF_FCC_vids)
- return buf;
-
- if (!gst_avi_demux_is_uncompressed (stream->strh->fcc_handler)) {
- return buf; /* Ignore non DIB buffers */
- }
-
- s = gst_caps_get_structure (GST_PAD_CAPS (stream->pad), 0);
- if (!gst_structure_get_int (s, "bpp", &bpp)) {
- GST_WARNING ("Failed to retrieve depth from caps");
- return buf;
- }
-
- if (stream->strf.vids == NULL) {
- GST_WARNING ("Failed to retrieve vids for stream");
- return buf;
- }
-
- h = stream->strf.vids->height;
- w = stream->strf.vids->width;
- stride = w * (bpp / 8);
-
- buf = gst_buffer_make_writable (buf);
- if (GST_BUFFER_SIZE (buf) < (stride * h)) {
- GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
- return buf;
- }
-
- tmp = g_malloc (stride);
-
- for (y = 0; y < h / 2; y++) {
- swap_line (GST_BUFFER_DATA (buf) + stride * y,
- GST_BUFFER_DATA (buf) + stride * (h - 1 - y), tmp, stride);
- }
-
- g_free (tmp);
-
- return buf;
-}
-
-/*
- * Returns the aggregated GstFlowReturn.
- */
-static GstFlowReturn
-gst_avi_demux_combine_flows (GstAviDemux * avi, avi_stream_context * stream,
- GstFlowReturn ret)
-{
- guint i;
-
- /* store the value */
- stream->last_flow = ret;
-
- /* any other error that is not-linked can be returned right away */
- if (G_UNLIKELY (ret != GST_FLOW_NOT_LINKED))
- goto done;
-
- /* only return NOT_LINKED if all other pads returned NOT_LINKED */
- for (i = 0; i < avi->num_streams; i++) {
- avi_stream_context *ostream = &avi->stream[i];
-
- ret = ostream->last_flow;
- /* some other return value (must be SUCCESS but we can return
- * other values as well) */
- if (G_UNLIKELY (ret != GST_FLOW_NOT_LINKED))
- goto done;
- }
- /* if we get here, all other pads were unlinked and we return
- * NOT_LINKED then */
-done:
- GST_LOG_OBJECT (avi, "combined return %s", gst_flow_get_name (ret));
- return ret;
-}
-
-/*
- * prepare the avi element for a reverse jump to a prev keyframe
- * this function will return the start entry. if the function returns
- * NULL there was no prev keyframe.
- */
-static gst_avi_index_entry *
-gst_avi_demux_step_reverse (GstAviDemux * avi)
-{
- gst_avi_index_entry *entry;
- gint i;
-
- avi->reverse_stop_index = avi->reverse_start_index;
- entry =
- gst_avi_demux_index_prev (avi, 0, avi->reverse_stop_index,
- GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME);
- if (!entry) {
- GST_DEBUG_OBJECT (avi, "no valid index entry found index %d",
- avi->reverse_stop_index);
- return NULL;
- }
- avi->current_entry = avi->reverse_start_index = entry->index_nr;
- GST_DEBUG_OBJECT (avi,
- "reverse playback jump: start idx (%d) and stop idx (%d)",
- avi->reverse_start_index, avi->reverse_stop_index);
- gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, entry->ts);
- for (i = 0; i < avi->num_streams; i++) {
- avi->stream[i].last_flow = GST_FLOW_OK;
- avi->stream[i].discont = TRUE;
- }
- return entry;
-}
-
-/*
- * Read data from one index entry
- */
-static GstFlowReturn
-gst_avi_demux_process_next_entry (GstAviDemux * avi)
-{
- GstFlowReturn res = GST_FLOW_OK;
- gboolean processed = FALSE;
- avi_stream_context *stream;
- gst_avi_index_entry *entry;
- GstBuffer *buf;
-
- do {
- /* see if we are at the end */
- if ((avi->segment.rate > 0 && avi->current_entry >= avi->index_size))
- goto eos;
-
- /* get next entry, this will work as we checked for the index size above */
- entry = &avi->index_entries[avi->current_entry++];
-
- /* check for reverse playback */
- if (avi->segment.rate < 0 && avi->current_entry > avi->reverse_stop_index) {
- GST_LOG_OBJECT (avi, "stop_index %d reached", avi->reverse_stop_index);
-
- /* check if we have pushed enough data for this segment */
- if (avi->reverse_start_index == 0)
- goto eos_reverse_zero;
- if (avi->index_entries[avi->reverse_start_index].ts < avi->segment.start)
- goto eos_reverse_segment;
-
- if (!(entry = gst_avi_demux_step_reverse (avi)))
- goto eos;
-
- avi->current_entry++;
- }
-
- /* see if we have a valid stream, ignore if not
- * FIXME: can't we check this when building the index?
- * we check it in _parse_index(), _stream_scan()
- */
- if (entry->stream_nr >= avi->num_streams) {
- GST_WARNING_OBJECT (avi,
- "Entry %d has non-existing stream nr %d",
- avi->current_entry - 1, entry->stream_nr);
- continue;
- }
-
- /* get stream now */
- stream = &avi->stream[entry->stream_nr];
-
- if (avi->segment.rate > 0.0) {
- /* only check this for fowards playback for now */
- if ((entry->flags & GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME)
- && GST_CLOCK_TIME_IS_VALID (entry->ts)
- && GST_CLOCK_TIME_IS_VALID (avi->segment.stop)
- && (entry->ts > avi->segment.stop)) {
- goto eos_stop;
- }
- }
-
- /* skip empty entries */
- if (entry->size == 0 || !stream->pad) {
- GST_DEBUG_OBJECT (avi, "Skipping entry %d (%d, %p)",
- avi->current_entry - 1, entry->size, stream->pad);
- goto next;
- }
-
- GST_LOG ("reading buffer (size=%d) from stream %d at current pos %"
- G_GUINT64_FORMAT " (%llx)", entry->size, entry->stream_nr,
- avi->index_offset + entry->offset, avi->index_offset + entry->offset);
-
- /* pull in the data */
- res = gst_pad_pull_range (avi->sinkpad, entry->offset +
- avi->index_offset, entry->size, &buf);
- if (res != GST_FLOW_OK)
- goto pull_failed;
-
- /* check for short buffers, this is EOS as well */
- if (GST_BUFFER_SIZE (buf) < entry->size)
- goto short_buffer;
-
- /* invert the picture if needed */
- buf = gst_avi_demux_invert (stream, buf);
-
- /* mark non-keyframes */
- if (!(entry->flags & GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME))
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
-
- GST_BUFFER_TIMESTAMP (buf) = entry->ts;
- GST_BUFFER_DURATION (buf) = entry->dur;
- if (stream->strh->type == GST_RIFF_FCC_vids) {
- if (stream->current_frame >= 0)
- GST_BUFFER_OFFSET (buf) = stream->current_frame;
- else {
- gint64 framenum;
- GstFormat fmt = GST_FORMAT_DEFAULT;
-
- if (gst_pad_query_convert (stream->pad, GST_FORMAT_TIME, entry->ts,
- &fmt, &framenum))
- GST_BUFFER_OFFSET (buf) = framenum;
- else
- GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
- }
- } else
- GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
- GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
- gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
-
- GST_DEBUG_OBJECT (avi, "Pushing buffer of size %d, offset %"
- G_GUINT64_FORMAT " and time %"
- GST_TIME_FORMAT " on pad %s",
- GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf),
- GST_TIME_ARGS (entry->ts), GST_PAD_NAME (stream->pad));
-
- /* update current position in the segment */
- gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, entry->ts);
-
- /* mark discont when pending */
- if (stream->discont) {
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
- stream->discont = FALSE;
- }
-
- res = gst_pad_push (stream->pad, buf);
-
- /* mark as processed, we increment the frame and byte counters then
- * leave the while loop and return the GstFlowReturn */
- processed = TRUE;
- GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", entry->index_nr,
- gst_flow_get_name (res));
-
- if (avi->segment.rate < 0
- && entry->ts > avi->segment.stop && res == GST_FLOW_UNEXPECTED) {
- /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
- * we are at the end of the segment, so we just need to jump
- * back to the previous section.
- */
- GST_DEBUG_OBJECT (avi, "downstream has reached end of segment");
-
- if (!(entry = gst_avi_demux_step_reverse (avi)))
- goto eos;
-
- res = GST_FLOW_OK;
-
- stream->current_frame = entry->frames_before;
- stream->current_byte = entry->bytes_before;
-
- continue;
- }
-
- /* combine flows */
- res = gst_avi_demux_combine_flows (avi, stream, res);
-
- next:
- stream->current_frame = entry->frames_before + 1;
- stream->current_byte = entry->bytes_before + entry->size;
- } while (!processed);
-
-beach:
- GST_DEBUG_OBJECT (avi, "returning %s", gst_flow_get_name (res));
-
- return res;
-
- /* ERRORS */
-eos:
- {
- GST_LOG_OBJECT (avi, "Handled last index entry, setting EOS (%d > %d)",
- avi->current_entry, avi->index_size);
- /* we mark the first stream as EOS */
- res = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-eos_stop:
- {
- GST_LOG_OBJECT (avi, "Found keyframe after segment,"
- " setting EOS (%" GST_TIME_FORMAT " > %" GST_TIME_FORMAT ")",
- GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (avi->segment.stop));
- res = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-eos_reverse_zero:
- {
- GST_DEBUG_OBJECT (avi, "start_index was 0, setting EOS");
- res = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-eos_reverse_segment:
- {
- GST_DEBUG_OBJECT (avi, "full segment pushed, setting EOS");
- res = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-pull_failed:
- {
- GST_DEBUG_OBJECT (avi,
- "pull range failed: pos=%" G_GUINT64_FORMAT " size=%d",
- entry->offset + avi->index_offset, entry->size);
- goto beach;
- }
-short_buffer:
- {
- GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
- ", only got %d/%d bytes (truncated file?)", entry->offset +
- avi->index_offset, GST_BUFFER_SIZE (buf), entry->size);
- gst_buffer_unref (buf);
- res = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-}
-
-/*
- * Read data. If we have an index it delegates to
- * gst_avi_demux_process_next_entry().
- */
-static GstFlowReturn
-gst_avi_demux_stream_data (GstAviDemux * avi)
-{
- guint32 tag = 0;
- guint32 size = 0;
- gint stream_nr = 0;
- GstFlowReturn res = GST_FLOW_OK;
- GstFormat format = GST_FORMAT_TIME;
-
- /* if we have a avi->index_entries[], we don't want to read
- * the stream linearly, but seek to the next ts/index_entry. */
- if (G_LIKELY (avi->index_entries != NULL))
- return gst_avi_demux_process_next_entry (avi);
-
- if (G_UNLIKELY (avi->have_eos)) {
- /* Clean adapter, we're done */
- gst_adapter_clear (avi->adapter);
- return res;
- }
-
- /*
- if (!gst_avi_demux_sync (avi, &tag, FALSE))
- return FALSE;
- */
-
- /* Iterate until need more data, so adapter won't grow too much */
- while (1) {
- if (G_UNLIKELY (!gst_avi_demux_peek_chunk_info (avi, &tag, &size))) {
- return GST_FLOW_OK;
- }
-
- GST_DEBUG ("Trying chunk (%" GST_FOURCC_FORMAT "), size %d",
- GST_FOURCC_ARGS (tag), size);
-
- if (G_LIKELY ((tag & 0xff) >= '0' && (tag & 0xff) <= '9' &&
- ((tag >> 8) & 0xff) >= '0' && ((tag >> 8) & 0xff) <= '9')) {
- GST_LOG ("Chunk ok");
- } else if ((tag & 0xffff) == (('x' << 8) | 'i')) {
- GST_DEBUG ("Found sub-index tag");
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- if ((size > 0) && (size != -1)) {
- GST_DEBUG (" skipping %d bytes for now", size);
- gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
- }
- }
- return GST_FLOW_OK;
- } else if (tag == GST_RIFF_TAG_JUNK) {
- GST_DEBUG ("JUNK chunk, skipping");
- } else if (tag == GST_RIFF_TAG_idx1) {
- GST_DEBUG ("Found index tag, stream done");
- avi->have_eos = TRUE;
- return GST_FLOW_UNEXPECTED;
- } else if (tag == GST_RIFF_TAG_LIST) {
- /* movi chunks might be grouped in rec list */
- if (gst_adapter_available (avi->adapter) >= 12) {
- GST_DEBUG ("Found LIST tag, skipping LIST header");
- gst_adapter_flush (avi->adapter, 12);
- continue;
- }
- return GST_FLOW_OK;
- } else if (tag == GST_RIFF_TAG_JUNK) {
- /* rec list might contain JUNK chunks */
- GST_DEBUG ("Found JUNK tag");
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- if ((size > 0) && (size != -1)) {
- GST_DEBUG (" skipping %d bytes for now", size);
- gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
- continue;
- }
- }
- return GST_FLOW_OK;
- } else {
- GST_DEBUG ("No more stream chunks, send EOS");
- avi->have_eos = TRUE;
- return GST_FLOW_UNEXPECTED;
- }
-
- if (G_UNLIKELY (!gst_avi_demux_peek_chunk (avi, &tag, &size))) {
- if ((size == 0) || (size == -1))
- gst_adapter_flush (avi->adapter, 8);
- return GST_FLOW_OK;
- }
- GST_DEBUG ("chunk ID %" GST_FOURCC_FORMAT ", size %u",
- GST_FOURCC_ARGS (tag), size);
-
- stream_nr = CHUNKID_TO_STREAMNR (tag);
-
- if (G_UNLIKELY (stream_nr < 0 || stream_nr >= avi->num_streams)) {
- /* recoverable */
- GST_WARNING ("Invalid stream ID %d (%" GST_FOURCC_FORMAT ")",
- stream_nr, GST_FOURCC_ARGS (tag));
- avi->offset += 8 + ((size + 1) & ~1);
- gst_adapter_flush (avi->adapter, 8 + ((size + 1) & ~1));
- } else {
- avi_stream_context *stream;
- GstClockTime next_ts = 0;
- GstBuffer *buf;
-
- gst_adapter_flush (avi->adapter, 8);
-
- /* get buffer */
- buf = gst_adapter_take_buffer (avi->adapter, ((size + 1) & ~1));
- /* patch the size */
- GST_BUFFER_SIZE (buf) = size;
- avi->offset += 8 + ((size + 1) & ~1);
-
- stream = &avi->stream[stream_nr];
-
- /* set delay (if any)
- if (stream->strh->init_frames == stream->current_frame &&
- stream->delay == 0)
- stream->delay = next_ts;
- */
-
- stream->current_frame++;
- stream->current_byte += size;
-
- /* parsing of corresponding header may have failed */
- if (G_UNLIKELY (!stream->pad)) {
- GST_WARNING_OBJECT (avi, "no pad for stream ID %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (tag));
- gst_buffer_unref (buf);
- } else {
- GstClockTime dur_ts = 0;
-
- /* get time of this buffer */
- gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
- if (G_UNLIKELY (format != GST_FORMAT_TIME))
- goto wrong_format;
-
- /* invert the picture if needed */
- buf = gst_avi_demux_invert (stream, buf);
-
- gst_pad_query_position (stream->pad, &format, (gint64 *) & dur_ts);
- if (G_UNLIKELY (format != GST_FORMAT_TIME))
- goto wrong_format;
-
- GST_BUFFER_TIMESTAMP (buf) = next_ts;
- GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
- if (stream->strh->type == GST_RIFF_FCC_vids)
- GST_BUFFER_OFFSET (buf) = stream->current_frame - 1;
- else
- GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
-
- gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
- GST_DEBUG_OBJECT (avi,
- "Pushing buffer with time=%" GST_TIME_FORMAT
- ", offset %" G_GUINT64_FORMAT " and size %d over pad %s",
- GST_TIME_ARGS (next_ts), GST_BUFFER_OFFSET (buf), size,
- GST_PAD_NAME (stream->pad));
-
- /* update current position in the segment */
- gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, next_ts);
-
- /* mark discont when pending */
- if (G_UNLIKELY (stream->discont)) {
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
- stream->discont = FALSE;
- }
- res = gst_pad_push (stream->pad, buf);
-
- /* combine flows */
- res = gst_avi_demux_combine_flows (avi, stream, res);
- if (G_UNLIKELY (res != GST_FLOW_OK)) {
- GST_DEBUG ("Push failed; %s", gst_flow_get_name (res));
- return res;
- }
- }
- }
- }
-
-done:
- return res;
-
- /* ERRORS */
-wrong_format:
- {
- GST_DEBUG_OBJECT (avi, "format %s != GST_FORMAT_TIME",
- gst_format_get_name (format));
- res = GST_FLOW_ERROR;
- goto done;
- }
-}
-
-/*
- * Send pending tags.
- */
-static void
-push_tag_lists (GstAviDemux * avi)
-{
- guint i;
-
- if (!avi->got_tags)
- return;
-
- GST_DEBUG_OBJECT (avi, "Pushing pending tag lists");
-
- for (i = 0; i < avi->num_streams; i++)
- if (avi->stream[i].pad && avi->stream[i].taglist) {
- GST_DEBUG_OBJECT (avi->stream[i].pad, "Tags: %" GST_PTR_FORMAT,
- avi->stream[i].taglist);
- gst_element_found_tags_for_pad (GST_ELEMENT (avi), avi->stream[i].pad,
- avi->stream[i].taglist);
- avi->stream[i].taglist = NULL;
- }
-
- if (avi->globaltags == NULL)
- avi->globaltags = gst_tag_list_new ();
-
- gst_tag_list_add (avi->globaltags, GST_TAG_MERGE_REPLACE,
- GST_TAG_CONTAINER_FORMAT, "AVI", NULL);
-
- GST_DEBUG_OBJECT (avi, "Global tags: %" GST_PTR_FORMAT, avi->globaltags);
- gst_element_found_tags (GST_ELEMENT (avi), avi->globaltags);
- avi->globaltags = NULL;
- avi->got_tags = FALSE;
-}
-
-static void
-gst_avi_demux_loop (GstPad * pad)
-{
- GstFlowReturn res;
- GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
-
- switch (avi->state) {
- case GST_AVI_DEMUX_START:
- if (G_UNLIKELY ((res =
- gst_avi_demux_stream_init_pull (avi)) != GST_FLOW_OK)) {
- GST_WARNING ("stream_init flow: %s", gst_flow_get_name (res));
- goto pause;
- }
- avi->state = GST_AVI_DEMUX_HEADER;
- /* fall-through */
- case GST_AVI_DEMUX_HEADER:
- if (G_UNLIKELY ((res =
- gst_avi_demux_stream_header_pull (avi)) != GST_FLOW_OK)) {
- GST_WARNING ("stream_header flow: %s", gst_flow_get_name (res));
- goto pause;
- }
- avi->state = GST_AVI_DEMUX_MOVI;
- break;
- case GST_AVI_DEMUX_MOVI:
- if (G_UNLIKELY (avi->seek_event)) {
- gst_avi_demux_push_event (avi, avi->seek_event);
- avi->seek_event = NULL;
- }
- if (G_UNLIKELY (avi->got_tags)) {
- push_tag_lists (avi);
- }
- /* process each index entry in turn */
- res = gst_avi_demux_stream_data (avi);
-
- /* pause when error */
- if (G_UNLIKELY (res != GST_FLOW_OK)) {
- GST_INFO ("stream_movi flow: %s", gst_flow_get_name (res));
- goto pause;
- }
- break;
- default:
- GST_ERROR_OBJECT (avi, "unknown state %d", avi->state);
- res = GST_FLOW_ERROR;
- goto pause;
- }
-
- GST_LOG_OBJECT (avi, "state: %d res:%s", avi->state, gst_flow_get_name (res));
-
- return;
-
- /* ERRORS */
-pause:
- GST_LOG_OBJECT (avi, "pausing task, reason %s", gst_flow_get_name (res));
- avi->segment_running = FALSE;
- gst_pad_pause_task (avi->sinkpad);
-
- if (GST_FLOW_IS_FATAL (res) || (res == GST_FLOW_NOT_LINKED)) {
- gboolean push_eos = TRUE;
-
- if (res == GST_FLOW_UNEXPECTED) {
- /* handle end-of-stream/segment */
- if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
- gint64 stop;
-
- if ((stop = avi->segment.stop) == -1)
- stop = avi->segment.duration;
-
- GST_INFO_OBJECT (avi, "sending segment_done");
-
- gst_element_post_message
- (GST_ELEMENT (avi),
- gst_message_new_segment_done (GST_OBJECT (avi), GST_FORMAT_TIME,
- stop));
- push_eos = FALSE;
- }
- } else {
- /* for fatal errors we post an error message */
- GST_ELEMENT_ERROR (avi, STREAM, FAILED,
- (_("Internal data stream error.")),
- ("streaming stopped, reason %s", gst_flow_get_name (res)));
- }
- if (push_eos) {
- GST_INFO_OBJECT (avi, "sending eos");
- if (!gst_avi_demux_push_event (avi, gst_event_new_eos ()) &&
- (res == GST_FLOW_UNEXPECTED)) {
- GST_ELEMENT_ERROR (avi, STREAM, DEMUX,
- (NULL), ("got eos but no streams (yet)"));
- }
- }
- }
-}
-
-
-static GstFlowReturn
-gst_avi_demux_chain (GstPad * pad, GstBuffer * buf)
-{
- GstFlowReturn res;
- GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
-
- GST_DEBUG ("Store %d bytes in adapter", GST_BUFFER_SIZE (buf));
- gst_adapter_push (avi->adapter, buf);
-
- switch (avi->state) {
- case GST_AVI_DEMUX_START:
- if ((res = gst_avi_demux_stream_init_push (avi)) != GST_FLOW_OK) {
- GST_WARNING ("stream_init flow: %s", gst_flow_get_name (res));
- break;
- }
- break;
- case GST_AVI_DEMUX_HEADER:
- if ((res = gst_avi_demux_stream_header_push (avi)) != GST_FLOW_OK) {
- GST_WARNING ("stream_header flow: %s", gst_flow_get_name (res));
- break;
- }
- break;
- case GST_AVI_DEMUX_MOVI:
- if (G_UNLIKELY (avi->seek_event)) {
- gst_avi_demux_push_event (avi, avi->seek_event);
- avi->seek_event = NULL;
- }
- if (G_UNLIKELY (avi->got_tags)) {
- push_tag_lists (avi);
- }
- res = gst_avi_demux_stream_data (avi);
- break;
- default:
- GST_ELEMENT_ERROR (avi, STREAM, FAILED, (NULL),
- ("Illegal internal state"));
- res = GST_FLOW_ERROR;
- break;
- }
-
- GST_DEBUG_OBJECT (avi, "state: %d res:%s", avi->state,
- gst_flow_get_name (res));
-
- return res;
-}
-
-static gboolean
-gst_avi_demux_sink_activate (GstPad * sinkpad)
-{
- if (gst_pad_check_pull_range (sinkpad)) {
- GST_DEBUG ("going to pull mode");
- return gst_pad_activate_pull (sinkpad, TRUE);
- } else {
- GST_DEBUG ("going to push (streaming) mode");
- return gst_pad_activate_push (sinkpad, TRUE);
- }
-}
-
-static gboolean
-gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
-{
- GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (sinkpad));
-
- if (active) {
- avi->segment_running = TRUE;
- avi->streaming = FALSE;
- return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop,
- sinkpad);
- } else {
- avi->segment_running = FALSE;
- return gst_pad_stop_task (sinkpad);
- }
-}
-
-static gboolean
-gst_avi_demux_activate_push (GstPad * pad, gboolean active)
-{
- GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (pad));
-
- if (active) {
- GST_DEBUG ("avi: activating push/chain function");
- avi->streaming = TRUE;
- } else {
- GST_DEBUG ("avi: deactivating push/chain function");
- }
-
- return TRUE;
-}
-
-static GstStateChangeReturn
-gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstAviDemux *avi = GST_AVI_DEMUX (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- avi->streaming = FALSE;
- gst_segment_init (&avi->segment, GST_FORMAT_TIME);
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto done;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_avi_demux_reset (avi);
- break;
- default:
- break;
- }
-
-done:
- return ret;
-}
--- a/gst_plugins_good/gst/avi/gstavidemux.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2006> Nokia Corporation (contact <stefan.kost@nokia.com>)
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_AVI_DEMUX_H__
-#define __GST_AVI_DEMUX_H__
-
-#include <gst/gst.h>
-
-#include "avi-ids.h"
-#include "gst/riff/riff-ids.h"
-#include "gst/riff/riff-read.h"
-#include <gst/base/gstadapter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AVI_DEMUX \
- (gst_avi_demux_get_type ())
-#define GST_AVI_DEMUX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AVI_DEMUX, GstAviDemux))
-#define GST_AVI_DEMUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AVI_DEMUX, GstAviDemuxClass))
-#define GST_IS_AVI_DEMUX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AVI_DEMUX))
-#define GST_IS_AVI_DEMUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AVI_DEMUX))
-
-#define GST_AVI_DEMUX_MAX_STREAMS 16
-
-#define CHUNKID_TO_STREAMNR(chunkid) \
- ((((chunkid) & 0xff) - '0') * 10 + \
- (((chunkid) >> 8) & 0xff) - '0')
-
-#define GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME 1
-
-/* 48 bytes */
-typedef struct {
- guint index_nr; /* = (entry-index_entries)/sizeof(gst_avi_index_entry); */
- guchar stream_nr;
- guchar flags;
- guint64 ts;
- guint64 dur; /* =entry[1].ts-entry->ts */
- guint64 offset;
- guint64 bytes_before; /* calculated */
- guint32 frames_before; /* calculated */
- guint32 size; /* could be read from the chunk (if we don't split) */
-} gst_avi_index_entry;
-
-typedef struct {
- /* index of this streamcontext */
- guint num;
-
- /* pad*/
- GstPad *pad;
-
- /* stream info and headers */
- gst_riff_strh *strh;
- union {
- gst_riff_strf_vids *vids;
- gst_riff_strf_auds *auds;
- gst_riff_strf_iavs *iavs;
- gpointer data;
- } strf;
- GstBuffer *extradata, *initdata;
- gchar *name;
-
- /* current position (byte, frame, time) and other status vars */
- guint current_frame;
- guint64 current_byte;
- GstFlowReturn last_flow;
- gboolean discont;
-
- /* stream length */
- guint64 total_bytes;
- guint32 total_frames;
- guint32 total_blocks;
- /* stream length according to index */
- GstClockTime idx_duration;
- /* stream length according to header */
- GstClockTime hdr_duration;
- /* stream length based on header/index */
- GstClockTime duration;
-
- /* VBR indicator */
- gboolean is_vbr;
-
- /* openDML support (for files >4GB) */
- gboolean superindex;
- guint64 *indexes;
-
- GstTagList *taglist;
-} avi_stream_context;
-
-typedef enum {
- GST_AVI_DEMUX_START,
- GST_AVI_DEMUX_HEADER,
- GST_AVI_DEMUX_MOVI,
-} GstAviDemuxState;
-
-typedef enum {
- GST_AVI_DEMUX_HEADER_TAG_LIST,
- GST_AVI_DEMUX_HEADER_AVIH,
- GST_AVI_DEMUX_HEADER_ELEMENTS,
- GST_AVI_DEMUX_HEADER_INFO,
- GST_AVI_DEMUX_HEADER_JUNK,
- GST_AVI_DEMUX_HEADER_DATA
-} GstAviDemuxHeaderState;
-
-typedef struct _GstAviDemux {
- GstElement parent;
-
- /* pads */
- GstPad *sinkpad;
-
- /* AVI decoding state */
- GstAviDemuxState state;
- GstAviDemuxHeaderState header_state;
- guint64 offset;
-
- /* index */
- gst_avi_index_entry *index_entries;
- guint index_size;
- guint64 index_offset;
- guint current_entry;
- guint reverse_start_index;
- guint reverse_stop_index;
-
- /* streams */
- guint num_streams;
- guint num_v_streams;
- guint num_a_streams;
- guint num_t_streams; /* subtitle text streams */
-
- avi_stream_context stream[GST_AVI_DEMUX_MAX_STREAMS];
-
- /* for streaming mode */
- gboolean streaming;
- gboolean have_eos;
- GstAdapter *adapter;
-
- /* some stream info for length */
- gst_riff_avih *avih;
-
- /* segment in TIME */
- GstSegment segment;
- gboolean segment_running;
-
- /* pending tags/events */
- GstEvent *seek_event;
- GstTagList *globaltags;
- gboolean got_tags;
-
-} GstAviDemux;
-
-typedef struct _GstAviDemuxClass {
- GstElementClass parent_class;
-} GstAviDemuxClass;
-
-GType gst_avi_demux_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_AVI_DEMUX_H__ */
--- a/gst_plugins_good/gst/avi/gstavimux.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1982 +0,0 @@
-/* AVI muxer plugin for GStreamer
- * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * (C) 2006 Mark Nauwelaerts <manauw@skynet.be>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* based on:
- * - the old avimuxer (by Wim Taymans)
- * - xawtv's aviwriter (by Gerd Knorr)
- * - mjpegtools' avilib (by Rainer Johanni)
- * - openDML large-AVI docs
- */
-
-/**
- * SECTION:element-avimux
- *
- * Muxes raw or compressed audio and/or video streams into an AVI file.
- *
- * <refsect2>
- * <title>Example launch lines</title>
- * <para>(write everything in one line, without the backslash characters)</para>
- * |[
- * gst-launch videotestsrc num-buffers=250 \
- * ! 'video/x-raw-yuv,format=(fourcc)I420,width=320,height=240,framerate=(fraction)25/1' \
- * ! queue ! mux. \
- * audiotestsrc num-buffers=440 ! audioconvert \
- * ! 'audio/x-raw-int,rate=44100,channels=2' ! queue ! mux. \
- * avimux name=mux ! filesink location=test.avi
- * ]| This will create an .AVI file containing an uncompressed video stream
- * with a test picture and an uncompressed audio stream containing a
- * test sound.
- * |[
- * gst-launch videotestsrc num-buffers=250 \
- * ! 'video/x-raw-yuv,format=(fourcc)I420,width=320,height=240,framerate=(fraction)25/1' \
- * ! xvidenc ! queue ! mux. \
- * audiotestsrc num-buffers=440 ! audioconvert ! 'audio/x-raw-int,rate=44100,channels=2' \
- * ! lame ! queue ! mux. \
- * avimux name=mux ! filesink location=test.avi
- * ]| This will create an .AVI file containing the same test video and sound
- * as above, only that both streams will be compressed this time. This will
- * only work if you have the necessary encoder elements installed of course.
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gst/gst-i18n-plugin.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include <gst/video/video.h>
-
-#include "gstavimux.h"
-
-GST_DEBUG_CATEGORY_STATIC (avimux_debug);
-#define GST_CAT_DEFAULT avimux_debug
-
-enum
-{
- ARG_0,
- ARG_BIGFILE
-};
-
-#define DEFAULT_BIGFILE TRUE
-
-static const GstElementDetails gst_avi_mux_details =
-GST_ELEMENT_DETAILS ("Avi muxer",
- "Codec/Muxer",
- "Muxes audio and video into an avi stream",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-
-static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-msvideo")
- );
-
-static GstStaticPadTemplate video_sink_factory =
- GST_STATIC_PAD_TEMPLATE ("video_%d",
- GST_PAD_SINK,
- GST_PAD_REQUEST,
- GST_STATIC_CAPS ("video/x-raw-yuv, "
- "format = (fourcc) { YUY2, I420 }, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "image/jpeg, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "video/x-divx, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ], "
- "divxversion = (int) [ 3, 5 ]; "
- "video/x-xvid, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "video/x-3ivx, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "video/x-msmpeg, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ], "
- "msmpegversion = (int) [ 41, 43 ]; "
- "video/mpeg, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ], "
- "mpegversion = (int) { 1, 2, 4}, "
- "systemstream = (boolean) FALSE; "
- "video/x-h263, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "video/x-h264, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], "
- "framerate = (fraction) [ 0, MAX ]; "
- "video/x-dv, "
- "width = (int) 720, "
- "height = (int) { 576, 480 }, "
- "framerate = (fraction) [ 0, MAX ], "
- "systemstream = (boolean) FALSE; "
- "video/x-huffyuv, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0, MAX ];"
- "video/x-dirac, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0, MAX ];"
- "video/x-wmv, "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0, MAX ], "
- "wmvversion = (int) [ 1, 3]")
- );
-
-static GstStaticPadTemplate audio_sink_factory =
- GST_STATIC_PAD_TEMPLATE ("audio_%d",
- GST_PAD_SINK,
- GST_PAD_REQUEST,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) LITTLE_ENDIAN, "
- "signed = (boolean) { TRUE, FALSE }, "
- "width = (int) { 8, 16 }, "
- "depth = (int) { 8, 16 }, "
- "rate = (int) [ 1000, 96000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/mpeg, "
- "mpegversion = (int) 1, "
- "layer = (int) [ 1, 3 ], "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
- "audio/mpeg, "
- "mpegversion = (int) 4, "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
-/*#if 0 VC6 doesn't support #if here ...
- "audio/x-vorbis, "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
-#endif*/
- "audio/x-ac3, "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
- "audio/x-alaw, "
- "rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]; "
- "audio/x-mulaw, "
- "rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]; "
- "audio/x-wma, "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ], "
- "wmaversion = (int) [ 1, 2 ] ")
- );
-
-static void gst_avi_mux_base_init (gpointer g_class);
-static void gst_avi_mux_class_init (GstAviMuxClass * klass);
-static void gst_avi_mux_init (GstAviMux * avimux);
-static void gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free);
-
-static GstFlowReturn gst_avi_mux_collect_pads (GstCollectPads * pads,
- GstAviMux * avimux);
-static gboolean gst_avi_mux_handle_event (GstPad * pad, GstEvent * event);
-static GstPad *gst_avi_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * name);
-static void gst_avi_mux_release_pad (GstElement * element, GstPad * pad);
-static void gst_avi_mux_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_avi_mux_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_avi_mux_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_avi_mux_get_type (void)
-{
- static GType avimux_type = 0;
-
- if (!avimux_type) {
- static const GTypeInfo avimux_info = {
- sizeof (GstAviMuxClass),
- gst_avi_mux_base_init,
- NULL,
- (GClassInitFunc) gst_avi_mux_class_init,
- NULL,
- NULL,
- sizeof (GstAviMux),
- 0,
- (GInstanceInitFunc) gst_avi_mux_init,
- };
- static const GInterfaceInfo tag_setter_info = {
- NULL,
- NULL,
- NULL
- };
-
- avimux_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstAviMux", &avimux_info, 0);
- g_type_add_interface_static (avimux_type, GST_TYPE_TAG_SETTER,
- &tag_setter_info);
- }
- return avimux_type;
-}
-
-static void
-gst_avi_mux_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&audio_sink_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&video_sink_factory));
-
- gst_element_class_set_details (element_class, &gst_avi_mux_details);
-
- GST_DEBUG_CATEGORY_INIT (avimux_debug, "avimux", 0, "Muxer for AVI streams");
-}
-
-static void
-gst_avi_mux_finalize (GObject * object)
-{
- GstAviMux *mux = GST_AVI_MUX (object);
- GSList *node;
-
- /* completely free each sinkpad */
- node = mux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- node = node->next;
-
- gst_avi_mux_pad_reset (avipad, TRUE);
- g_free (avipad);
- }
- g_slist_free (mux->sinkpads);
- mux->sinkpads = NULL;
-
- g_free (mux->idx);
- mux->idx = NULL;
-
- gst_object_unref (mux->collect);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_avi_mux_class_init (GstAviMuxClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->get_property = gst_avi_mux_get_property;
- gobject_class->set_property = gst_avi_mux_set_property;
- gobject_class->finalize = gst_avi_mux_finalize;
-
- g_object_class_install_property (gobject_class, ARG_BIGFILE,
- g_param_spec_boolean ("bigfile", "Bigfile Support (>2GB)",
- "Support for openDML-2.0 (big) AVI files", DEFAULT_BIGFILE,
- G_PARAM_READWRITE));
-
- gstelement_class->request_new_pad =
- GST_DEBUG_FUNCPTR (gst_avi_mux_request_new_pad);
- gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_avi_mux_release_pad);
- gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avi_mux_change_state);
-}
-
-/* reset pad to initial state
- * free - if true, release all, not only stream related, data */
-static void
-gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free)
-{
- /* generic part */
- memset (&(avipad->hdr), 0, sizeof (gst_riff_strh));
-
- memset (&(avipad->idx[0]), 0, sizeof (avipad->idx));
-
- if (free) {
- g_free (avipad->tag);
- avipad->tag = NULL;
- g_free (avipad->idx_tag);
- avipad->idx_tag = NULL;
- }
-
- if (avipad->is_video) {
- GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;
-
- avipad->hdr.type = GST_MAKE_FOURCC ('v', 'i', 'd', 's');
- if (vidpad->vids_codec_data) {
- gst_buffer_unref (vidpad->vids_codec_data);
- vidpad->vids_codec_data = NULL;
- }
-
- memset (&(vidpad->vids), 0, sizeof (gst_riff_strf_vids));
- memset (&(vidpad->vprp), 0, sizeof (gst_riff_vprp));
- } else {
- GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
-
- avipad->hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
- if (audpad->auds_codec_data) {
- gst_buffer_unref (audpad->auds_codec_data);
- audpad->auds_codec_data = NULL;
- }
-
- memset (&(audpad->auds), 0, sizeof (gst_riff_strf_auds));
- }
-}
-
-static void
-gst_avi_mux_reset (GstAviMux * avimux)
-{
- GSList *node, *newlist = NULL;
-
- /* free and reset each sinkpad */
- node = avimux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- node = node->next;
-
- gst_avi_mux_pad_reset (avipad, FALSE);
- /* if this pad has collectdata, keep it, otherwise dump it completely */
- if (avipad->collect)
- newlist = g_slist_append (newlist, avipad);
- else {
- gst_avi_mux_pad_reset (avipad, TRUE);
- g_free (avipad);
- }
- }
-
- /* free the old list of sinkpads, only keep the real collecting ones */
- g_slist_free (avimux->sinkpads);
- avimux->sinkpads = newlist;
-
- /* avi data */
- avimux->num_frames = 0;
- memset (&(avimux->avi_hdr), 0, sizeof (gst_riff_avih));
- avimux->avi_hdr.max_bps = 10000000;
- avimux->codec_data_size = 0;
-
- if (avimux->tags_snap) {
- gst_tag_list_free (avimux->tags_snap);
- avimux->tags_snap = NULL;
- }
-
- g_free (avimux->idx);
- avimux->idx = NULL;
-
- /* state info */
- avimux->write_header = TRUE;
-
- /* tags */
- gst_tag_setter_reset_tags (GST_TAG_SETTER (avimux));
-}
-
-static void
-gst_avi_mux_init (GstAviMux * avimux)
-{
- avimux->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
- gst_pad_use_fixed_caps (avimux->srcpad);
- gst_element_add_pad (GST_ELEMENT (avimux), avimux->srcpad);
-
- /* property */
- avimux->enable_large_avi = DEFAULT_BIGFILE;
-
- avimux->collect = gst_collect_pads_new ();
- gst_collect_pads_set_function (avimux->collect,
- (GstCollectPadsFunction) (GST_DEBUG_FUNCPTR (gst_avi_mux_collect_pads)),
- avimux);
-
- /* set to clean state */
- gst_avi_mux_reset (avimux);
-}
-
-static gboolean
-gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
-{
- GstAviMux *avimux;
- GstAviVideoPad *avipad;
- GstAviCollectData *collect_pad;
- GstStructure *structure;
- const gchar *mimetype;
- const GValue *fps, *par;
- const GValue *codec_data;
- gint width, height;
- gint par_n, par_d;
-
- avimux = GST_AVI_MUX (gst_pad_get_parent (pad));
-
- /* find stream data */
- collect_pad = (GstAviCollectData *) gst_pad_get_element_private (pad);
- g_assert (collect_pad);
- avipad = (GstAviVideoPad *) collect_pad->avipad;
- g_assert (avipad);
- g_assert (avipad->parent.is_video);
- g_assert (avipad->parent.hdr.type == GST_MAKE_FOURCC ('v', 'i', 'd', 's'));
-
- GST_DEBUG_OBJECT (avimux, "%s:%s, caps=%" GST_PTR_FORMAT,
- GST_DEBUG_PAD_NAME (pad), vscaps);
-
- structure = gst_caps_get_structure (vscaps, 0);
- mimetype = gst_structure_get_name (structure);
-
- /* global */
- avipad->vids.size = sizeof (gst_riff_strf_vids);
- avipad->vids.planes = 1;
- if (!gst_structure_get_int (structure, "width", &width) ||
- !gst_structure_get_int (structure, "height", &height)) {
- goto refuse_caps;
- }
-
- avipad->vids.width = width;
- avipad->vids.height = height;
-
- fps = gst_structure_get_value (structure, "framerate");
- if (fps == NULL || !GST_VALUE_HOLDS_FRACTION (fps))
- goto refuse_caps;
-
- avipad->parent.hdr.rate = gst_value_get_fraction_numerator (fps);
- avipad->parent.hdr.scale = gst_value_get_fraction_denominator (fps);
-
- /* (pixel) aspect ratio data, if any */
- par = gst_structure_get_value (structure, "pixel-aspect-ratio");
- /* only use video properties header if there is non-trivial aspect info */
- if (par && GST_VALUE_HOLDS_FRACTION (par) &&
- ((par_n = gst_value_get_fraction_numerator (par)) !=
- (par_d = gst_value_get_fraction_denominator (par)))) {
- GValue to_ratio = { 0, };
- guint ratio_n, ratio_d;
-
- /* some fraction voodoo to obtain simplest possible ratio */
- g_value_init (&to_ratio, GST_TYPE_FRACTION);
- gst_value_set_fraction (&to_ratio, width * par_n, height * par_d);
- ratio_n = gst_value_get_fraction_numerator (&to_ratio);
- ratio_d = gst_value_get_fraction_denominator (&to_ratio);
- GST_DEBUG_OBJECT (avimux, "generating vprp data with aspect ratio %d/%d",
- ratio_n, ratio_d);
- /* simply fill in */
- avipad->vprp.vert_rate = avipad->parent.hdr.rate / avipad->parent.hdr.scale;
- avipad->vprp.hor_t_total = width;
- avipad->vprp.vert_lines = height;
- avipad->vprp.aspect = (ratio_n) << 16 | (ratio_d & 0xffff);
- avipad->vprp.width = width;
- avipad->vprp.height = height;
- avipad->vprp.fields = 1;
- avipad->vprp.field_info[0].compressed_bm_height = height;
- avipad->vprp.field_info[0].compressed_bm_width = width;
- avipad->vprp.field_info[0].valid_bm_height = height;
- avipad->vprp.field_info[0].valid_bm_width = width;
- }
-
- /* codec initialization data, if any */
- codec_data = gst_structure_get_value (structure, "codec_data");
- if (codec_data) {
- avipad->vids_codec_data = gst_value_get_buffer (codec_data);
- gst_buffer_ref (avipad->vids_codec_data);
- /* keep global track of size */
- avimux->codec_data_size += GST_BUFFER_SIZE (avipad->vids_codec_data);
- }
-
- if (!strcmp (mimetype, "video/x-raw-yuv")) {
- guint32 format;
-
- gst_structure_get_fourcc (structure, "format", &format);
- avipad->vids.compression = format;
- switch (format) {
- case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
- avipad->vids.bit_cnt = 16;
- break;
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- avipad->vids.bit_cnt = 12;
- break;
- }
- } else {
- avipad->vids.bit_cnt = 24;
- avipad->vids.compression = 0;
-
- /* find format */
- if (!strcmp (mimetype, "video/x-huffyuv")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('H', 'F', 'Y', 'U');
- } else if (!strcmp (mimetype, "image/jpeg")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'J', 'P', 'G');
- } else if (!strcmp (mimetype, "video/x-divx")) {
- gint divxversion;
-
- gst_structure_get_int (structure, "divxversion", &divxversion);
- switch (divxversion) {
- case 3:
- avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', '3');
- break;
- case 4:
- avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
- break;
- case 5:
- avipad->vids.compression = GST_MAKE_FOURCC ('D', 'X', '5', '0');
- break;
- }
- } else if (!strcmp (mimetype, "video/x-xvid")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('X', 'V', 'I', 'D');
- } else if (!strcmp (mimetype, "video/x-3ivx")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('3', 'I', 'V', '2');
- } else if (gst_structure_has_name (structure, "video/x-msmpeg")) {
- gint msmpegversion;
-
- gst_structure_get_int (structure, "msmpegversion", &msmpegversion);
- switch (msmpegversion) {
- case 41:
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'G', '4');
- break;
- case 42:
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', '4', '2');
- break;
- case 43:
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', '4', '3');
- break;
- default:
- GST_INFO ("unhandled msmpegversion : %d, fall back to fourcc=MPEG",
- msmpegversion);
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'E', 'G');
- break;
- }
- } else if (!strcmp (mimetype, "video/x-dv")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('D', 'V', 'S', 'D');
- } else if (!strcmp (mimetype, "video/x-h263")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('H', '2', '6', '3');
- } else if (!strcmp (mimetype, "video/x-h264")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('H', '2', '6', '4');
- } else if (!strcmp (mimetype, "video/mpeg")) {
- gint mpegversion;
-
- gst_structure_get_int (structure, "mpegversion", &mpegversion);
-
- switch (mpegversion) {
- case 2:
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'G', '2');
- break;
- case 4:
- /* mplayer/ffmpeg might not work with DIVX, but with FMP4 */
- avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
- break;
- default:
- GST_INFO ("unhandled mpegversion : %d, fall back to fourcc=MPEG",
- mpegversion);
- avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'E', 'G');
- break;
- }
- } else if (!strcmp (mimetype, "video/x-dirac")) {
- avipad->vids.compression = GST_MAKE_FOURCC ('d', 'r', 'a', 'c');
- } else if (!strcmp (mimetype, "video/x-wmv")) {
- gint wmvversion;
-
- if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
- switch (wmvversion) {
- case 1:
- avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '1');
- break;
- case 2:
- avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
- break;
- case 3:
- avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
- default:
- break;
- }
- }
- }
-
- if (!avipad->vids.compression)
- goto refuse_caps;
- }
-
- avipad->parent.hdr.fcc_handler = avipad->vids.compression;
- avipad->vids.image_size = avipad->vids.height * avipad->vids.width;
- /* hm, maybe why avi only handles one stream well ... */
- avimux->avi_hdr.width = avipad->vids.width;
- avimux->avi_hdr.height = avipad->vids.height;
- avimux->avi_hdr.us_frame = 1000000. * avipad->parent.hdr.scale /
- avipad->parent.hdr.rate;
-
- gst_object_unref (avimux);
- return TRUE;
-
-refuse_caps:
- {
- GST_WARNING_OBJECT (avimux, "refused caps %" GST_PTR_FORMAT, vscaps);
- gst_object_unref (avimux);
- return FALSE;
- }
-}
-
-static gboolean
-gst_avi_mux_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
-{
- GstAviMux *avimux;
- GstAviAudioPad *avipad;
- GstAviCollectData *collect_pad;
- GstStructure *structure;
- const gchar *mimetype;
- const GValue *codec_data;
- gint channels, rate;
-
- avimux = GST_AVI_MUX (gst_pad_get_parent (pad));
-
- /* find stream data */
- collect_pad = (GstAviCollectData *) gst_pad_get_element_private (pad);
- g_assert (collect_pad);
- avipad = (GstAviAudioPad *) collect_pad->avipad;
- g_assert (avipad);
- g_assert (!avipad->parent.is_video);
- g_assert (avipad->parent.hdr.type == GST_MAKE_FOURCC ('a', 'u', 'd', 's'));
-
- GST_DEBUG_OBJECT (avimux, "%s:%s, caps=%" GST_PTR_FORMAT,
- GST_DEBUG_PAD_NAME (pad), vscaps);
-
- structure = gst_caps_get_structure (vscaps, 0);
- mimetype = gst_structure_get_name (structure);
-
- /* we want these for all */
- if (!gst_structure_get_int (structure, "channels", &channels) ||
- !gst_structure_get_int (structure, "rate", &rate)) {
- goto refuse_caps;
- }
-
- avipad->auds.channels = channels;
- avipad->auds.rate = rate;
-
- /* codec initialization data, if any */
- codec_data = gst_structure_get_value (structure, "codec_data");
- if (codec_data) {
- avipad->auds_codec_data = gst_value_get_buffer (codec_data);
- gst_buffer_ref (avipad->auds_codec_data);
- /* keep global track of size */
- avimux->codec_data_size += GST_BUFFER_SIZE (avipad->auds_codec_data);
- }
-
- if (!strcmp (mimetype, "audio/x-raw-int")) {
- gint width, depth;
- gboolean signedness;
-
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_PCM;
-
- if (!gst_structure_get_int (structure, "width", &width) ||
- !gst_structure_get_int (structure, "depth", &depth) ||
- !gst_structure_get_boolean (structure, "signed", &signedness)) {
- GST_DEBUG_OBJECT (avimux,
- "broken caps, width/depth/signed field missing");
- goto refuse_caps;
- }
-
- /* no clear place to put different values for these while keeping to spec */
- if (width != depth) {
- GST_DEBUG_OBJECT (avimux, "width must be same as depth!");
- goto refuse_caps;
- }
-
- /* because that's the way the caps will be recreated from riff data */
- if ((width == 8 && signedness) || (width == 16 && !signedness)) {
- GST_DEBUG_OBJECT (avimux,
- "8-bit PCM must be unsigned, 16-bit PCM signed");
- goto refuse_caps;
- }
-
- avipad->auds.blockalign = width;
- avipad->auds.size = (width == 8) ? 8 : depth;
-
- /* set some more info straight */
- avipad->auds.blockalign /= 8;
- avipad->auds.blockalign *= avipad->auds.channels;
- avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
- } else {
- avipad->auds.format = 0;
- /* set some defaults */
- avipad->auds.blockalign = 1;
- avipad->auds.av_bps = 0;
- avipad->auds.size = 16;
-
- if (!strcmp (mimetype, "audio/mpeg")) {
- gint mpegversion;
-
- gst_structure_get_int (structure, "mpegversion", &mpegversion);
- switch (mpegversion) {
- case 1:{
- gint layer = 3;
-
- gst_structure_get_int (structure, "layer", &layer);
- switch (layer) {
- case 3:
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL3;
- break;
- case 1:
- case 2:
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL12;
- break;
- }
- break;
- }
- case 4:
- GST_WARNING ("AAC");
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_AAC;
- break;
- }
- } else if (!strcmp (mimetype, "audio/x-vorbis")) {
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_VORBIS3;
- } else if (!strcmp (mimetype, "audio/x-ac3")) {
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_A52;
- } else if (!strcmp (mimetype, "audio/x-alaw")) {
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_ALAW;
- avipad->auds.size = 8;
- avipad->auds.blockalign = avipad->auds.channels;
- avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
- } else if (!strcmp (mimetype, "audio/x-mulaw")) {
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_MULAW;
- avipad->auds.size = 8;
- avipad->auds.blockalign = avipad->auds.channels;
- avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
- } else if (!strcmp (mimetype, "audio/x-wma")) {
- gint version;
- gint bitrate;
- gint block_align;
-
- if (gst_structure_get_int (structure, "wmaversion", &version)) {
- switch (version) {
- case 1:
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_WMAV1;
- break;
- case 2:
- avipad->auds.format = GST_RIFF_WAVE_FORMAT_WMAV2;
- break;
- default:
- break;
- }
- }
-
- if (avipad->auds.format != 0) {
- if (gst_structure_get_int (structure, "block_align", &block_align)) {
- avipad->auds.blockalign = block_align;
- }
- if (gst_structure_get_int (structure, "bitrate", &bitrate)) {
- avipad->auds.av_bps = bitrate / 8;
- }
- }
- }
- }
-
- if (!avipad->auds.format)
- goto refuse_caps;
-
- /* by spec, hdr.rate is av_bps related, is calculated that way in stop_file,
- * and reduces to sample rate in PCM like cases */
- avipad->parent.hdr.rate = avipad->auds.av_bps / avipad->auds.blockalign;
- avipad->parent.hdr.samplesize = avipad->auds.blockalign;
- avipad->parent.hdr.scale = 1;
-
- gst_object_unref (avimux);
- return TRUE;
-
-refuse_caps:
- {
- GST_WARNING_OBJECT (avimux, "refused caps %" GST_PTR_FORMAT, vscaps);
- gst_object_unref (avimux);
- return FALSE;
- }
-}
-
-
-static GstPad *
-gst_avi_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * req_name)
-{
- GstAviMux *avimux;
- GstPad *newpad;
- GstAviPad *avipad;
- GstElementClass *klass;
-
- g_return_val_if_fail (templ != NULL, NULL);
-
- if (templ->direction != GST_PAD_SINK)
- goto wrong_direction;
-
- g_return_val_if_fail (GST_IS_AVI_MUX (element), NULL);
- avimux = GST_AVI_MUX (element);
-
- if (!avimux->write_header)
- goto too_late;
-
- klass = GST_ELEMENT_GET_CLASS (element);
-
- if (templ == gst_element_class_get_pad_template (klass, "audio_%d")) {
- gchar *name;
-
- /* setup pad */
- name = g_strdup_printf ("audio_%02d", avimux->audio_pads);
- GST_DEBUG_OBJECT (avimux, "adding new pad: %s", name);
- newpad = gst_pad_new_from_template (templ, name);
- g_free (name);
- gst_pad_set_setcaps_function (newpad,
- GST_DEBUG_FUNCPTR (gst_avi_mux_audsink_set_caps));
-
- /* init pad specific data */
- avipad = g_malloc0 (sizeof (GstAviAudioPad));
- avipad->is_video = FALSE;
- avipad->hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
- avimux->audio_pads++;
- /* audio goes last */
- avimux->sinkpads = g_slist_append (avimux->sinkpads, avipad);
- } else if (templ == gst_element_class_get_pad_template (klass, "video_%d")) {
- /* though streams are pretty generic and relatively self-contained,
- * some video info goes in a single avi header -and therefore mux struct-
- * so video restricted to one stream */
- if (avimux->video_pads > 0)
- return NULL;
- /* setup pad */
- GST_DEBUG_OBJECT (avimux, "adding new pad: video_00");
- newpad = gst_pad_new_from_template (templ, "video_00");
- gst_pad_set_setcaps_function (newpad,
- GST_DEBUG_FUNCPTR (gst_avi_mux_vidsink_set_caps));
- avipad = g_malloc0 (sizeof (GstAviVideoPad));
-
- /* init pad specific data */
- avipad->is_video = TRUE;
- avipad->hdr.type = GST_MAKE_FOURCC ('v', 'i', 'd', 's');
- avimux->video_pads++;
- /* video goes first */
- avimux->sinkpads = g_slist_prepend (avimux->sinkpads, avipad);
- } else
- goto wrong_template;
-
- avipad->collect = gst_collect_pads_add_pad (avimux->collect,
- newpad, sizeof (GstAviCollectData));
- ((GstAviCollectData *) (avipad->collect))->avipad = avipad;
- /* FIXME: hacked way to override/extend the event function of
- * GstCollectPads; because it sets its own event function giving the
- * element no access to events */
- avimux->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad);
- gst_pad_set_event_function (newpad,
- GST_DEBUG_FUNCPTR (gst_avi_mux_handle_event));
-
- gst_element_add_pad (element, newpad);
-
- return newpad;
-
- /* ERRORS */
-wrong_direction:
- {
- g_warning ("avimux: request pad that is not a SINK pad\n");
- return NULL;
- }
-too_late:
- {
- g_warning ("avimux: request pad cannot be added after streaming started\n");
- return NULL;
- }
-wrong_template:
- {
- g_warning ("avimuxx: this is not our template!\n");
- return NULL;
- }
-}
-
-static void
-gst_avi_mux_release_pad (GstElement * element, GstPad * pad)
-{
- GstAviMux *avimux = GST_AVI_MUX (element);
- GSList *node;
-
- node = avimux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- if (avipad->collect->pad == pad) {
- /* pad count should not be adjusted,
- * as it also represent number of streams present */
- avipad->collect = NULL;
- GST_DEBUG_OBJECT (avimux, "removed pad '%s'", GST_PAD_NAME (pad));
- gst_collect_pads_remove_pad (avimux->collect, pad);
- gst_element_remove_pad (element, pad);
- /* if not started yet, we can remove any sign this pad ever existed */
- /* in this case _start will take care of the real pad count */
- if (avimux->write_header) {
- avimux->sinkpads = g_slist_remove (avimux->sinkpads, avipad);
- gst_avi_mux_pad_reset (avipad, TRUE);
- g_free (avipad);
- }
- return;
- }
-
- node = node->next;
- }
-
- g_warning ("Unknown pad %s", GST_PAD_NAME (pad));
-}
-
-/* maybe some of these functions should be moved to riff.h? */
-
-/* DISCLAIMER: this function is fairly ugly. So be it (i.e. it makes the rest easier)
- * so is this struct */
-
-typedef struct _GstMarkedBuffer
-{
- guint *highmark;
- GstBuffer *buffer;
-} GstMarkedBuffer;
-
-static void
-gst_avi_mux_write_tag (const GstTagList * list, const gchar * tag,
- gpointer data)
-{
- const struct
- {
- guint32 fcc;
- gchar *tag;
- } rifftags[] = {
- {
- GST_RIFF_INFO_IARL, GST_TAG_LOCATION}, {
- GST_RIFF_INFO_IART, GST_TAG_ARTIST}, {
- GST_RIFF_INFO_ICMT, GST_TAG_COMMENT}, {
- GST_RIFF_INFO_ICOP, GST_TAG_COPYRIGHT}, {
- GST_RIFF_INFO_ICRD, GST_TAG_DATE}, {
- GST_RIFF_INFO_IGNR, GST_TAG_GENRE}, {
- GST_RIFF_INFO_IKEY, GST_TAG_KEYWORDS}, {
- GST_RIFF_INFO_INAM, GST_TAG_TITLE}, {
- GST_RIFF_INFO_ISFT, GST_TAG_ENCODER}, {
- GST_RIFF_INFO_ISRC, GST_TAG_ISRC}, {
- 0, NULL}
- };
- gint n, len, plen;
- GstBuffer *buf = ((GstMarkedBuffer *) data)->buffer;
- guint *highmark = ((GstMarkedBuffer *) data)->highmark;
- guint8 *buffdata = GST_BUFFER_DATA (buf) + *highmark;
- gchar *str;
-
- for (n = 0; rifftags[n].fcc != 0; n++) {
- if (!strcmp (rifftags[n].tag, tag) &&
- gst_tag_list_get_string (list, tag, &str) && str) {
- len = strlen (str);
- plen = len + 1;
- if (plen & 1)
- plen++;
- if (GST_BUFFER_SIZE (buf) >= *highmark + 8 + plen) {
- GST_WRITE_UINT32_LE (buffdata, rifftags[n].fcc);
- GST_WRITE_UINT32_LE (buffdata + 4, len + 1);
- memcpy (buffdata + 8, str, len);
- buffdata[8 + len] = 0;
- *highmark += 8 + plen;
- GST_DEBUG ("writing tag in buffer %p, highmark at %d", buf, *highmark);
- }
- g_free (str);
- break;
- }
- }
-}
-
-#define ODML_SUPERINDEX_SIZE \
- (32 + GST_AVI_SUPERINDEX_COUNT * sizeof (gst_avi_superindex_entry))
-
-static GstBuffer *
-gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
-{
- const GstTagList *tags;
- GstBuffer *buffer;
- guint8 *buffdata;
- guint size = 0;
- guint highmark = 0;
-
- /* pointer to list size field */
- guint8 *riff_size, *hdrl_size;
- GSList *node;
-
- GST_DEBUG_OBJECT (avimux, "creating avi header, data_size %u, idx_size %u",
- avimux->data_size, avimux->idx_size);
-
- if (avimux->tags_snap)
- tags = avimux->tags_snap;
- else {
- /* need to make snapshot of current state of tags to ensure the same set
- * is used next time around during header rewrite at the end */
- tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (avimux));
- if (tags)
- tags = avimux->tags_snap = gst_tag_list_copy (tags);
- }
- if (tags) {
- /* that should be the strlen of all tags + header sizes
- * not all of tags end up in a avi, still this is a good estimate
- */
- gchar *str = gst_structure_to_string (tags);
- size += strlen (str) + 8 * gst_structure_n_fields (tags);
- g_free (str);
- }
-
- /* allocate the buffer, starting with some wild/safe upper bound */
- size += avimux->codec_data_size + 100 + sizeof (gst_riff_avih)
- + (g_slist_length (avimux->sinkpads) * (100 + sizeof (gst_riff_strh_full)
- + sizeof (gst_riff_strf_vids)
- + sizeof (gst_riff_vprp)
- + sizeof (gst_riff_vprp_video_field_desc) * 2
- + sizeof (gst_riff_strf_auds) + 2 + ODML_SUPERINDEX_SIZE));
- buffer = gst_buffer_new_and_alloc (size);
- buffdata = GST_BUFFER_DATA (buffer);
- highmark = 0;
- GST_DEBUG_OBJECT (avimux, "creating buffer %p, size %d, highmark at 0",
- buffer, GST_BUFFER_SIZE (buffer));
-
- /* avi header metadata */
- memcpy (buffdata + 0, "RIFF", 4);
- /* fill in RIFF size later */
- riff_size = buffdata + 4;
- memcpy (buffdata + 8, "AVI ", 4);
- memcpy (buffdata + 12, "LIST", 4);
- /* fill in header size later */
- hdrl_size = buffdata + 16;
- memcpy (buffdata + 20, "hdrl", 4);
- memcpy (buffdata + 24, "avih", 4);
- GST_WRITE_UINT32_LE (buffdata + 28, sizeof (gst_riff_avih));
- buffdata += 32;
- highmark += 32;
-
- /* the AVI header itself */
- GST_WRITE_UINT32_LE (buffdata + 0, avimux->avi_hdr.us_frame);
- GST_WRITE_UINT32_LE (buffdata + 4, avimux->avi_hdr.max_bps);
- GST_WRITE_UINT32_LE (buffdata + 8, avimux->avi_hdr.pad_gran);
- GST_WRITE_UINT32_LE (buffdata + 12, avimux->avi_hdr.flags);
- GST_WRITE_UINT32_LE (buffdata + 16, avimux->avi_hdr.tot_frames);
- GST_WRITE_UINT32_LE (buffdata + 20, avimux->avi_hdr.init_frames);
- GST_WRITE_UINT32_LE (buffdata + 24, avimux->avi_hdr.streams);
- GST_WRITE_UINT32_LE (buffdata + 28, avimux->avi_hdr.bufsize);
- GST_WRITE_UINT32_LE (buffdata + 32, avimux->avi_hdr.width);
- GST_WRITE_UINT32_LE (buffdata + 36, avimux->avi_hdr.height);
- GST_WRITE_UINT32_LE (buffdata + 40, avimux->avi_hdr.scale);
- GST_WRITE_UINT32_LE (buffdata + 44, avimux->avi_hdr.rate);
- GST_WRITE_UINT32_LE (buffdata + 48, avimux->avi_hdr.start);
- GST_WRITE_UINT32_LE (buffdata + 52, avimux->avi_hdr.length);
- buffdata += 56;
- highmark += 56;
-
- /* stream data */
- node = avimux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
- GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;
- GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
- guint codec_size = 0, strl_size = 0, vprp_size = 0;
-
- if (avipad->is_video) {
- if (vidpad->vids_codec_data)
- codec_size = GST_BUFFER_SIZE (vidpad->vids_codec_data);
- strl_size = sizeof (gst_riff_strh_full) + sizeof (gst_riff_strf_vids)
- + GST_ROUND_UP_2 (codec_size) + 4 * 5 + ODML_SUPERINDEX_SIZE;
- if (vidpad->vprp.aspect) {
- /* let's be on the safe side */
- vidpad->vprp.fields = MIN (vidpad->vprp.fields,
- GST_RIFF_VPRP_VIDEO_FIELDS);
- vprp_size = G_STRUCT_OFFSET (gst_riff_vprp, field_info)
- + (vidpad->vprp.fields * sizeof (gst_riff_vprp_video_field_desc));
- strl_size += 4 * 2 + vprp_size;
- }
- } else {
- if (audpad->auds_codec_data)
- codec_size = GST_BUFFER_SIZE (audpad->auds_codec_data);
- /* +2 is codec_size field, not part of gst_riff_strf_auds */
- strl_size = sizeof (gst_riff_strh_full) + sizeof (gst_riff_strf_auds) + 2
- + GST_ROUND_UP_2 (codec_size) + 4 * 5 + ODML_SUPERINDEX_SIZE;
- }
-
- /* stream list metadata */
- memcpy (buffdata + 0, "LIST", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, strl_size);
- memcpy (buffdata + 8, "strl", 4);
- /* generic header */
- memcpy (buffdata + 12, "strh", 4);
- GST_WRITE_UINT32_LE (buffdata + 16, sizeof (gst_riff_strh_full));
- /* the actual header */
- GST_WRITE_UINT32_LE (buffdata + 20, avipad->hdr.type);
- GST_WRITE_UINT32_LE (buffdata + 24, avipad->hdr.fcc_handler);
- GST_WRITE_UINT32_LE (buffdata + 28, avipad->hdr.flags);
- GST_WRITE_UINT32_LE (buffdata + 32, avipad->hdr.priority);
- GST_WRITE_UINT32_LE (buffdata + 36, avipad->hdr.init_frames);
- GST_WRITE_UINT32_LE (buffdata + 40, avipad->hdr.scale);
- GST_WRITE_UINT32_LE (buffdata + 44, avipad->hdr.rate);
- GST_WRITE_UINT32_LE (buffdata + 48, avipad->hdr.start);
- GST_WRITE_UINT32_LE (buffdata + 52, avipad->hdr.length);
- GST_WRITE_UINT32_LE (buffdata + 56, avipad->hdr.bufsize);
- GST_WRITE_UINT32_LE (buffdata + 60, avipad->hdr.quality);
- GST_WRITE_UINT32_LE (buffdata + 64, avipad->hdr.samplesize);
- GST_WRITE_UINT16_LE (buffdata + 68, 0);
- GST_WRITE_UINT16_LE (buffdata + 70, 0);
- GST_WRITE_UINT16_LE (buffdata + 72, 0);
- GST_WRITE_UINT16_LE (buffdata + 74, 0);
- buffdata += 76;
- highmark += 76;
-
- if (avipad->is_video) {
- /* the video header */
- memcpy (buffdata + 0, "strf", 4);
- GST_WRITE_UINT32_LE (buffdata + 4,
- sizeof (gst_riff_strf_vids) + codec_size);
- /* the actual header */
- GST_WRITE_UINT32_LE (buffdata + 8, vidpad->vids.size + codec_size);
- GST_WRITE_UINT32_LE (buffdata + 12, vidpad->vids.width);
- GST_WRITE_UINT32_LE (buffdata + 16, vidpad->vids.height);
- GST_WRITE_UINT16_LE (buffdata + 20, vidpad->vids.planes);
- GST_WRITE_UINT16_LE (buffdata + 22, vidpad->vids.bit_cnt);
- GST_WRITE_UINT32_LE (buffdata + 24, vidpad->vids.compression);
- GST_WRITE_UINT32_LE (buffdata + 28, vidpad->vids.image_size);
- GST_WRITE_UINT32_LE (buffdata + 32, vidpad->vids.xpels_meter);
- GST_WRITE_UINT32_LE (buffdata + 36, vidpad->vids.ypels_meter);
- GST_WRITE_UINT32_LE (buffdata + 40, vidpad->vids.num_colors);
- GST_WRITE_UINT32_LE (buffdata + 44, vidpad->vids.imp_colors);
- buffdata += 48;
- highmark += 48;
-
- /* include codec data, if any */
- if (codec_size) {
- memcpy (buffdata, GST_BUFFER_DATA (vidpad->vids_codec_data),
- codec_size);
-
- buffdata += codec_size;
- highmark += codec_size;
- }
- /* padding */
- if (highmark & 0x1) {
- highmark++;
- buffdata++;
- }
-
- /* add video property data, mainly for aspect ratio, if any */
- if (vprp_size) {
- gint f;
-
- /* the vprp header */
- memcpy (buffdata + 0, "vprp", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, vprp_size);
- /* the actual data */
- GST_WRITE_UINT32_LE (buffdata + 8, vidpad->vprp.format_token);
- GST_WRITE_UINT32_LE (buffdata + 12, vidpad->vprp.standard);
- GST_WRITE_UINT32_LE (buffdata + 16, vidpad->vprp.vert_rate);
- GST_WRITE_UINT32_LE (buffdata + 20, vidpad->vprp.hor_t_total);
- GST_WRITE_UINT32_LE (buffdata + 24, vidpad->vprp.vert_lines);
- GST_WRITE_UINT32_LE (buffdata + 28, vidpad->vprp.aspect);
- GST_WRITE_UINT32_LE (buffdata + 32, vidpad->vprp.width);
- GST_WRITE_UINT32_LE (buffdata + 36, vidpad->vprp.height);
- GST_WRITE_UINT32_LE (buffdata + 40, vidpad->vprp.fields);
- buffdata += 44;
- highmark += 44;
- for (f = 0; f < vidpad->vprp.fields; ++f) {
- gst_riff_vprp_video_field_desc *fd;
-
- fd = &(vidpad->vprp.field_info[f]);
- GST_WRITE_UINT32_LE (buffdata + 0, fd->compressed_bm_height);
- GST_WRITE_UINT32_LE (buffdata + 4, fd->compressed_bm_width);
- GST_WRITE_UINT32_LE (buffdata + 8, fd->valid_bm_height);
- GST_WRITE_UINT32_LE (buffdata + 12, fd->valid_bm_width);
- GST_WRITE_UINT32_LE (buffdata + 16, fd->valid_bm_x_offset);
- GST_WRITE_UINT32_LE (buffdata + 20, fd->valid_bm_y_offset);
- GST_WRITE_UINT32_LE (buffdata + 24, fd->video_x_t_offset);
- GST_WRITE_UINT32_LE (buffdata + 28, fd->video_y_start);
- buffdata += 32;
- highmark += 32;
- }
- }
- } else {
- /* the audio header */
- memcpy (buffdata + 0, "strf", 4);
- GST_WRITE_UINT32_LE (buffdata + 4,
- sizeof (gst_riff_strf_auds) + 2 + codec_size);
- /* the actual header */
- GST_WRITE_UINT16_LE (buffdata + 8, audpad->auds.format);
- GST_WRITE_UINT16_LE (buffdata + 10, audpad->auds.channels);
- GST_WRITE_UINT32_LE (buffdata + 12, audpad->auds.rate);
- GST_WRITE_UINT32_LE (buffdata + 16, audpad->auds.av_bps);
- GST_WRITE_UINT16_LE (buffdata + 20, audpad->auds.blockalign);
- GST_WRITE_UINT16_LE (buffdata + 22, audpad->auds.size);
- GST_WRITE_UINT16_LE (buffdata + 24, codec_size);
- buffdata += 26;
- highmark += 26;
-
- /* include codec data, if any */
- if (codec_size) {
- memcpy (buffdata, GST_BUFFER_DATA (audpad->auds_codec_data),
- codec_size);
-
- buffdata += codec_size;
- highmark += codec_size;
- }
- /* padding */
- if (highmark & 0x1) {
- highmark++;
- buffdata++;
- }
- }
-
- /* odml superindex chunk */
- if (avipad->idx_index > 0)
- memcpy (buffdata, "indx", 4);
- else
- memcpy (buffdata, "JUNK", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, ODML_SUPERINDEX_SIZE - 8); /* chunk size */
- GST_WRITE_UINT16_LE (buffdata + 8, 4); /* bytes per entry */
- buffdata[10] = 0; /* index subtype */
- buffdata[11] = GST_AVI_INDEX_OF_INDEXES; /* index type */
- GST_WRITE_UINT32_LE (buffdata + 12, avipad->idx_index); /* entries in use */
- memcpy (buffdata + 16, avipad->tag, 4); /* stream id */
- GST_WRITE_UINT32_LE (buffdata + 20, 0); /* reserved */
- GST_WRITE_UINT32_LE (buffdata + 24, 0); /* reserved */
- GST_WRITE_UINT32_LE (buffdata + 28, 0); /* reserved */
- memcpy (buffdata + 32, avipad->idx,
- GST_AVI_SUPERINDEX_COUNT * sizeof (gst_avi_superindex_entry));
- buffdata += ODML_SUPERINDEX_SIZE;
- highmark += ODML_SUPERINDEX_SIZE;
-
- node = node->next;
- }
-
- if (avimux->video_pads > 0) {
- /* odml header */
- memcpy (buffdata + 0, "LIST", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, sizeof (guint32) + 4 * 3);
- memcpy (buffdata + 8, "odml", 4);
- memcpy (buffdata + 12, "dmlh", 4);
- GST_WRITE_UINT32_LE (buffdata + 16, sizeof (guint32));
- GST_WRITE_UINT32_LE (buffdata + 20, avimux->total_frames);
- buffdata += 24;
- highmark += 24;
- }
-
- GST_WRITE_UINT32_LE (hdrl_size, (guint32) (buffdata - hdrl_size) - 4);
-
- /* tags */
- if (tags) {
- guint8 *ptr;
- guint startsize;
- GstMarkedBuffer data ;
- data.highmark = &highmark;
- data.buffer = buffer;
-
- memcpy (buffdata + 0, "LIST", 4);
- ptr = buffdata + 4; /* fill in later */
- startsize = highmark + 4;
- memcpy (buffdata + 8, "INFO", 4);
- buffdata += 12;
- highmark += 12;
-
- /* 12 bytes is needed for data header */
- GST_BUFFER_SIZE (buffer) -= 12;
- gst_tag_list_foreach (tags, gst_avi_mux_write_tag, &data);
- GST_BUFFER_SIZE (buffer) += 12;
- buffdata = GST_BUFFER_DATA (buffer) + highmark;
-
- /* update list size */
- GST_WRITE_UINT32_LE (ptr, highmark - startsize - 4);
- }
-
- /* avi data header */
- memcpy (buffdata + 0, "LIST", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, avimux->data_size);
- memcpy (buffdata + 8, "movi", 4);
- buffdata += 12;
- highmark += 12;
-
- /* finally we can fill in the RIFF size */
- /* note that riff only counts the first avi chunk */
- GST_WRITE_UINT32_LE (riff_size, (guint32) (buffdata - riff_size - 4) /* header and movi tags */
- +avimux->idx_size + avimux->data_size - 4); /* movi data and index */
-
- { /* only the part that is filled in actually makes up the header
- * unref the parent as we only need this part from now on */
- GstBuffer *subbuffer = gst_buffer_create_sub (buffer, 0, highmark);
-
- gst_buffer_unref (buffer);
- return subbuffer;
- }
-}
-
-static GstBuffer *
-gst_avi_mux_riff_get_avix_header (guint32 datax_size)
-{
- GstBuffer *buffer;
- guint8 *buffdata;
-
- buffer = gst_buffer_new_and_alloc (24);
- buffdata = GST_BUFFER_DATA (buffer);
-
- memcpy (buffdata + 0, "RIFF", 4);
- GST_WRITE_UINT32_LE (buffdata + 4, datax_size + 3 * 4);
- memcpy (buffdata + 8, "AVIX", 4);
- memcpy (buffdata + 12, "LIST", 4);
- GST_WRITE_UINT32_LE (buffdata + 16, datax_size);
- memcpy (buffdata + 20, "movi", 4);
-
- return buffer;
-}
-
-static inline GstBuffer *
-gst_avi_mux_riff_get_header (GstAviPad * avipad, guint32 video_frame_size)
-{
- GstBuffer *buffer;
- guint8 *buffdata;
-
- buffer = gst_buffer_new_and_alloc (8);
- buffdata = GST_BUFFER_DATA (buffer);
- memcpy (buffdata + 0, avipad->tag, 4);
- GST_WRITE_UINT32_LE (buffdata + 4, video_frame_size);
-
- return buffer;
-}
-
-/* write an odml index chunk in the movi list */
-static GstFlowReturn
-gst_avi_mux_write_avix_index (GstAviMux * avimux, gchar * code,
- gchar * chunk, gst_avi_superindex_entry * super_index,
- gint * super_index_count)
-{
- GstFlowReturn res;
- GstBuffer *buffer;
- guint8 *buffdata, *data;
- gst_riff_index_entry *entry;
- gint i;
- guint32 size, entry_count;
-
- /* allocate the maximum possible */
- buffer = gst_buffer_new_and_alloc (32 + 8 * avimux->idx_index);
- buffdata = GST_BUFFER_DATA (buffer);
-
- /* general index chunk info */
- memcpy (buffdata + 0, chunk, 4); /* chunk id */
- GST_WRITE_UINT32_LE (buffdata + 4, 0); /* chunk size; fill later */
- GST_WRITE_UINT16_LE (buffdata + 8, 2); /* index entry is 2 words */
- buffdata[10] = 0; /* index subtype */
- buffdata[11] = GST_AVI_INDEX_OF_CHUNKS; /* index type: AVI_INDEX_OF_CHUNKS */
- GST_WRITE_UINT32_LE (buffdata + 12, 0); /* entries in use; fill later */
- memcpy (buffdata + 16, code, 4); /* stream to which index refers */
- GST_WRITE_UINT64_LE (buffdata + 20, avimux->avix_start); /* base offset */
- GST_WRITE_UINT32_LE (buffdata + 28, 0); /* reserved */
- buffdata += 32;
-
- /* now the actual index entries */
- i = avimux->idx_index;
- entry = avimux->idx;
- while (i > 0) {
- if (memcmp (&entry->id, code, 4) == 0) {
- /* enter relative offset to the data (!) */
- GST_WRITE_UINT32_LE (buffdata, GUINT32_FROM_LE (entry->offset) + 8);
- /* msb is set if not (!) keyframe */
- GST_WRITE_UINT32_LE (buffdata + 4, GUINT32_FROM_LE (entry->size)
- | (GUINT32_FROM_LE (entry->flags)
- & GST_RIFF_IF_KEYFRAME ? 0 : 1U << 31));
- buffdata += 8;
- }
- i--;
- entry++;
- }
-
- /* ok, now we know the size and no of entries, fill in where needed */
- data = GST_BUFFER_DATA (buffer);
- GST_BUFFER_SIZE (buffer) = size = buffdata - data;
- GST_WRITE_UINT32_LE (data + 4, size - 8);
- entry_count = (size - 32) / 8;
- GST_WRITE_UINT32_LE (data + 12, entry_count);
-
- /* decorate and send */
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
- if ((res = gst_pad_push (avimux->srcpad, buffer)) != GST_FLOW_OK)
- return res;
-
- /* keep track of this in superindex (if room) ... */
- if (*super_index_count < GST_AVI_SUPERINDEX_COUNT) {
- i = *super_index_count;
- super_index[i].offset = GUINT64_TO_LE (avimux->total_data);
- super_index[i].size = GUINT32_TO_LE (size);
- super_index[i].duration = GUINT32_TO_LE (entry_count);
- (*super_index_count)++;
- } else
- GST_WARNING_OBJECT (avimux, "No more room in superindex of stream %s",
- code);
-
- /* ... and in size */
- avimux->total_data += size;
- if (avimux->is_bigfile)
- avimux->datax_size += size;
- else
- avimux->data_size += size;
-
- return GST_FLOW_OK;
-}
-
-/* some other usable functions (thankyou xawtv ;-) ) */
-
-static void
-gst_avi_mux_add_index (GstAviMux * avimux, gchar * code, guint32 flags,
- guint32 size)
-{
- if (avimux->idx_index == avimux->idx_count) {
- avimux->idx_count += 256;
- avimux->idx =
- g_realloc (avimux->idx,
- avimux->idx_count * sizeof (gst_riff_index_entry));
- }
- memcpy (&(avimux->idx[avimux->idx_index].id), code, 4);
- avimux->idx[avimux->idx_index].flags = GUINT32_TO_LE (flags);
- avimux->idx[avimux->idx_index].offset = GUINT32_TO_LE (avimux->idx_offset);
- avimux->idx[avimux->idx_index].size = GUINT32_TO_LE (size);
- avimux->idx_index++;
-}
-
-static GstFlowReturn
-gst_avi_mux_write_index (GstAviMux * avimux)
-{
- GstFlowReturn res;
- GstBuffer *buffer;
- guint8 *buffdata;
-
- buffer = gst_buffer_new_and_alloc (8);
- buffdata = GST_BUFFER_DATA (buffer);
- memcpy (buffdata + 0, "idx1", 4);
- GST_WRITE_UINT32_LE (buffdata + 4,
- avimux->idx_index * sizeof (gst_riff_index_entry));
-
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
- res = gst_pad_push (avimux->srcpad, buffer);
- if (res != GST_FLOW_OK)
- return res;
-
- buffer = gst_buffer_new ();
- GST_BUFFER_SIZE (buffer) = avimux->idx_index * sizeof (gst_riff_index_entry);
- GST_BUFFER_DATA (buffer) = (guint8 *) avimux->idx;
- GST_BUFFER_MALLOCDATA (buffer) = GST_BUFFER_DATA (buffer);
- avimux->idx = NULL; /* will be free()'ed by gst_buffer_unref() */
- avimux->total_data += GST_BUFFER_SIZE (buffer) + 8;
-
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
- res = gst_pad_push (avimux->srcpad, buffer);
- if (res != GST_FLOW_OK)
- return res;
-
- avimux->idx_size += avimux->idx_index * sizeof (gst_riff_index_entry) + 8;
-
- /* update header */
- avimux->avi_hdr.flags |= GST_RIFF_AVIH_HASINDEX;
- return GST_FLOW_OK;
-}
-
-static GstFlowReturn
-gst_avi_mux_bigfile (GstAviMux * avimux, gboolean last)
-{
- GstFlowReturn res = GST_FLOW_OK;
- GstBuffer *header;
- GstEvent *event;
- GSList *node;
-
- /* first some odml standard index chunks in the movi list */
- node = avimux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- node = node->next;
-
- res = gst_avi_mux_write_avix_index (avimux, avipad->tag,
- avipad->idx_tag, avipad->idx, &avipad->idx_index);
- if (res != GST_FLOW_OK)
- return res;
- }
-
- if (avimux->is_bigfile) {
- /* search back */
- event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- avimux->avix_start, GST_CLOCK_TIME_NONE, avimux->avix_start);
- /* if the event succeeds */
- gst_pad_push_event (avimux->srcpad, event);
-
- /* rewrite AVIX header */
- header = gst_avi_mux_riff_get_avix_header (avimux->datax_size);
- gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
- res = gst_pad_push (avimux->srcpad, header);
-
- /* go back to current location, at least try */
- event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- avimux->total_data, GST_CLOCK_TIME_NONE, avimux->total_data);
- gst_pad_push_event (avimux->srcpad, event);
-
- if (res != GST_FLOW_OK)
- return res;
- } else { /* write a standard index in the first riff chunk */
- res = gst_avi_mux_write_index (avimux);
- /* the index data/buffer is freed by pushing it */
- avimux->idx_count = 0;
- if (res != GST_FLOW_OK)
- return res;
- }
-
- avimux->avix_start = avimux->total_data;
-
- if (last)
- return res;
-
- avimux->is_bigfile = TRUE;
- avimux->numx_frames = 0;
- avimux->datax_size = 4; /* movi tag */
- avimux->idx_index = 0;
-
- header = gst_avi_mux_riff_get_avix_header (0);
- avimux->total_data += GST_BUFFER_SIZE (header);
- /* avix_start is used as base offset for the odml index chunk */
- avimux->idx_offset = avimux->total_data - avimux->avix_start;
- gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
- return gst_pad_push (avimux->srcpad, header);
-}
-
-/* enough header blabla now, let's go on to actually writing the headers */
-
-static GstFlowReturn
-gst_avi_mux_start_file (GstAviMux * avimux)
-{
- GstFlowReturn res;
- GstBuffer *header;
- GSList *node;
-
- avimux->total_data = 0;
- avimux->total_frames = 0;
- avimux->data_size = 4; /* movi tag */
- avimux->datax_size = 0;
- avimux->num_frames = 0;
- avimux->numx_frames = 0;
- avimux->avix_start = 0;
-
- avimux->idx_index = 0;
- avimux->idx_offset = 0; /* see 10 lines below */
- avimux->idx_size = 0;
- avimux->idx_count = 0;
- avimux->idx = NULL;
-
- /* state */
- avimux->write_header = FALSE;
- avimux->restart = FALSE;
-
- /* init streams, see what we've got */
- node = avimux->sinkpads;
- avimux->audio_pads = avimux->video_pads = 0;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- node = node->next;
-
- if (!avipad->is_video) {
- /* audio stream numbers must start at 1 iff there is a video stream 0;
- * request_pad inserts video pad at head of list, so this test suffices */
- if (avimux->video_pads)
- avimux->audio_pads++;
- avipad->tag = g_strdup_printf ("%02uwb", avimux->audio_pads);
- avipad->idx_tag = g_strdup_printf ("ix%02u", avimux->audio_pads);
- if (!avimux->video_pads)
- avimux->audio_pads++;
- } else {
- avipad->tag = g_strdup_printf ("%02udb", avimux->video_pads);
- avipad->idx_tag = g_strdup_printf ("ix%02u", avimux->video_pads++);
- }
- }
-
- /* let downstream know we think in BYTES and expect to do seeking later on */
- gst_pad_push_event (avimux->srcpad,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0));
-
- /* header */
- avimux->avi_hdr.streams = g_slist_length (avimux->sinkpads);
- avimux->is_bigfile = FALSE;
-
- header = gst_avi_mux_riff_get_avi_header (avimux);
- avimux->total_data += GST_BUFFER_SIZE (header);
-
- gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
- res = gst_pad_push (avimux->srcpad, header);
-
- avimux->idx_offset = avimux->total_data;
-
- return res;
-}
-
-static GstFlowReturn
-gst_avi_mux_stop_file (GstAviMux * avimux)
-{
- GstFlowReturn res = GST_FLOW_OK;
- GstEvent *event;
- GstBuffer *header;
- GSList *node;
-
- /* if bigfile, rewrite header, else write indexes */
- /* don't bail out at once if error, still try to re-write header */
- if (avimux->video_pads > 0) {
- if (avimux->is_bigfile) {
- res = gst_avi_mux_bigfile (avimux, TRUE);
- } else {
- res = gst_avi_mux_write_index (avimux);
- }
- }
-
- /* we do our best to make it interleaved at least ... */
- if (avimux->audio_pads > 0 && avimux->video_pads > 0)
- avimux->avi_hdr.flags |= GST_RIFF_AVIH_ISINTERLEAVED;
-
- /* set rate and everything having to do with that */
- avimux->avi_hdr.max_bps = 0;
- node = avimux->sinkpads;
- while (node) {
- GstAviPad *avipad = (GstAviPad *) node->data;
-
- node = node->next;
-
- if (!avipad->is_video) {
- GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
-
- /* calculate bps if needed */
- if (!audpad->auds.av_bps) {
- if (audpad->audio_time) {
- audpad->auds.av_bps =
- (GST_SECOND * audpad->audio_size) / audpad->audio_time;
- /* round bps to nearest multiple of 8;
- * which is much more likely to be the (cbr) bitrate in use;
- * which in turn results in better timestamp calculation on playback */
- audpad->auds.av_bps = GST_ROUND_UP_8 (audpad->auds.av_bps - 4);
- } else {
- GST_ELEMENT_WARNING (avimux, STREAM, MUX,
- (_("No or invalid input audio, AVI stream will be corrupt.")),
- (NULL));
- audpad->auds.av_bps = 0;
- }
- avipad->hdr.rate = audpad->auds.av_bps * avipad->hdr.scale;
- }
- avimux->avi_hdr.max_bps += audpad->auds.av_bps;
- avipad->hdr.length = (audpad->audio_time * avipad->hdr.rate) / GST_SECOND;
- } else {
- GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;
-
- avimux->avi_hdr.max_bps += ((vidpad->vids.bit_cnt + 7) / 8) *
- (1000000. / avimux->avi_hdr.us_frame) * vidpad->vids.image_size;
- avipad->hdr.length = avimux->total_frames;
- }
- }
-
- /* statistics/total_frames/... */
- avimux->avi_hdr.tot_frames = avimux->num_frames;
-
- /* seek and rewrite the header */
- header = gst_avi_mux_riff_get_avi_header (avimux);
- event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- 0, GST_CLOCK_TIME_NONE, 0);
- gst_pad_push_event (avimux->srcpad, event);
-
- gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
- /* the first error survives */
- if (res == GST_FLOW_OK)
- res = gst_pad_push (avimux->srcpad, header);
- else
- gst_pad_push (avimux->srcpad, header);
-
- event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- avimux->total_data, GST_CLOCK_TIME_NONE, avimux->total_data);
- gst_pad_push_event (avimux->srcpad, event);
-
- avimux->write_header = TRUE;
-
- return res;
-}
-
-static GstFlowReturn
-gst_avi_mux_restart_file (GstAviMux * avimux)
-{
- GstFlowReturn res;
-
- if ((res = gst_avi_mux_stop_file (avimux)) != GST_FLOW_OK)
- return res;
-
- gst_pad_push_event (avimux->srcpad, gst_event_new_eos ());
-
- return gst_avi_mux_start_file (avimux);
-}
-
-/* handle events (search) */
-static gboolean
-gst_avi_mux_handle_event (GstPad * pad, GstEvent * event)
-{
- GstAviMux *avimux;
- gboolean ret;
-
- avimux = GST_AVI_MUX (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_TAG:{
- GstTagList *list;
- GstTagSetter *setter = GST_TAG_SETTER (avimux);
- const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
-
- gst_event_parse_tag (event, &list);
- gst_tag_setter_merge_tags (setter, list, mode);
- break;
- }
- default:
- break;
- }
-
- /* now GstCollectPads can take care of the rest, e.g. EOS */
- ret = avimux->collect_event (pad, event);
-
- gst_object_unref (avimux);
-
- return ret;
-}
-
-/* send extra 'padding' data */
-static GstFlowReturn
-gst_avi_mux_send_pad_data (GstAviMux * avimux, gulong num_bytes)
-{
- GstBuffer *buffer;
-
- buffer = gst_buffer_new_and_alloc (num_bytes);
- memset (GST_BUFFER_DATA (buffer), 0, num_bytes);
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
- return gst_pad_push (avimux->srcpad, buffer);
-}
-
-/* do buffer */
-static GstFlowReturn
-gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
-{
- GstFlowReturn res;
- GstBuffer *data, *header;
- gulong total_size, pad_bytes = 0;
- guint flags;
-
- data = gst_collect_pads_pop (avimux->collect, avipad->collect);
-
- if (avimux->restart) {
- if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
- return res;
- }
-
- /* need to restart or start a next avix chunk ? */
- if ((avimux->is_bigfile ? avimux->datax_size : avimux->data_size) +
- GST_BUFFER_SIZE (data) > 1024 * 1024 * 2000) {
- if (avimux->enable_large_avi) {
- if ((res = gst_avi_mux_bigfile (avimux, FALSE)) != GST_FLOW_OK)
- return res;
- } else {
- if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
- return res;
- }
- }
-
- /* get header and record some stats */
- if (GST_BUFFER_SIZE (data) & 1) {
- pad_bytes = 2 - (GST_BUFFER_SIZE (data) & 1);
- }
- header = gst_avi_mux_riff_get_header (avipad, GST_BUFFER_SIZE (data));
- total_size = GST_BUFFER_SIZE (header) + GST_BUFFER_SIZE (data) + pad_bytes;
-
- if (avimux->is_bigfile) {
- avimux->datax_size += total_size;
- } else {
- avimux->data_size += total_size;
- }
-
- if (avipad->is_video) {
- avimux->total_frames++;
-
- if (avimux->is_bigfile) {
- avimux->numx_frames++;
- } else {
- avimux->num_frames++;
- }
-
- flags = 0x02;
- if (!GST_BUFFER_FLAG_IS_SET (data, GST_BUFFER_FLAG_DELTA_UNIT))
- flags |= 0x10;
- } else {
- GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
-
- flags = 0;
- audpad->audio_size += GST_BUFFER_SIZE (data);
- audpad->audio_time += GST_BUFFER_DURATION (data);
- }
-
- gst_avi_mux_add_index (avimux, avipad->tag, flags, GST_BUFFER_SIZE (data));
-
- /* prepare buffers for sending */
- gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
- data = gst_buffer_make_metadata_writable (data);
- gst_buffer_set_caps (data, GST_PAD_CAPS (avimux->srcpad));
-
- GST_LOG_OBJECT (avimux, "pushing buffers: head, data");
-
- if ((res = gst_pad_push (avimux->srcpad, header)) != GST_FLOW_OK)
- return res;
- if ((res = gst_pad_push (avimux->srcpad, data)) != GST_FLOW_OK)
- return res;
-
- if (pad_bytes) {
- if ((res = gst_avi_mux_send_pad_data (avimux, pad_bytes)) != GST_FLOW_OK)
- return res;
- }
-
- /* if any push above fails, we're in trouble with file consistency anyway */
- avimux->total_data += total_size;
- avimux->idx_offset += total_size;
-
- return res;
-}
-
-/* pick the oldest buffer from the pads and push it */
-static GstFlowReturn
-gst_avi_mux_do_one_buffer (GstAviMux * avimux)
-{
- GstAviPad *avipad, *best_pad;
- GSList *node;
- GstBuffer *buffer;
- GstClockTime time, best_time;
-
- node = avimux->sinkpads;
- best_pad = NULL;
- best_time = GST_CLOCK_TIME_NONE;
- for (; node; node = node->next) {
- avipad = (GstAviPad *) node->data;
-
- if (!avipad->collect)
- continue;
-
- buffer = gst_collect_pads_peek (avimux->collect, avipad->collect);
- if (!buffer)
- continue;
- time = GST_BUFFER_TIMESTAMP (buffer);
- gst_buffer_unref (buffer);
-
- /* invalid timestamp buffers pass first,
- * these are probably initialization buffers */
- if (best_pad == NULL || !GST_CLOCK_TIME_IS_VALID (time)
- || (GST_CLOCK_TIME_IS_VALID (best_time) && time < best_time)) {
- best_pad = avipad;
- best_time = time;
- }
- }
-
- if (best_pad) {
- GST_LOG_OBJECT (avimux, "selected pad %s with time %" GST_TIME_FORMAT,
- GST_PAD_NAME (best_pad->collect->pad), GST_TIME_ARGS (best_time));
-
- return gst_avi_mux_do_buffer (avimux, best_pad);
- } else {
- /* simply finish off the file and send EOS */
- gst_avi_mux_stop_file (avimux);
- gst_pad_push_event (avimux->srcpad, gst_event_new_eos ());
- return GST_FLOW_UNEXPECTED;
- }
-}
-
-static GstFlowReturn
-gst_avi_mux_collect_pads (GstCollectPads * pads, GstAviMux * avimux)
-{
- GstFlowReturn res;
-
- if (G_UNLIKELY (avimux->write_header)) {
- if ((res = gst_avi_mux_start_file (avimux)) != GST_FLOW_OK)
- return res;
- }
-
- return gst_avi_mux_do_one_buffer (avimux);
-}
-
-
-static void
-gst_avi_mux_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- GstAviMux *avimux;
-
- avimux = GST_AVI_MUX (object);
-
- switch (prop_id) {
- case ARG_BIGFILE:
- g_value_set_boolean (value, avimux->enable_large_avi);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_avi_mux_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
-{
- GstAviMux *avimux;
-
- avimux = GST_AVI_MUX (object);
-
- switch (prop_id) {
- case ARG_BIGFILE:
- avimux->enable_large_avi = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_avi_mux_change_state (GstElement * element, GstStateChange transition)
-{
- GstAviMux *avimux;
- GstStateChangeReturn ret;
-
- avimux = GST_AVI_MUX (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- gst_collect_pads_start (avimux->collect);
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_collect_pads_stop (avimux->collect);
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto done;
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_avi_mux_reset (avimux);
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
-
-done:
- return ret;
-}
--- a/gst_plugins_good/gst/avi/gstavimux.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/* AVI muxer plugin for GStreamer
- * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_AVI_MUX_H__
-#define __GST_AVI_MUX_H__
-
-
-#include <gst/gst.h>
-#include <gst/base/gstcollectpads.h>
-#include <gst/riff/riff-ids.h>
-#include "avi-ids.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_AVI_MUX \
- (gst_avi_mux_get_type())
-#define GST_AVI_MUX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVI_MUX,GstAviMux))
-#define GST_AVI_MUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVI_MUX,GstAviMuxClass))
-#define GST_IS_AVI_MUX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVI_MUX))
-#define GST_IS_AVI_MUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVI_MUX))
-
-#define GST_AVI_INDEX_OF_INDEXES 0
-#define GST_AVI_INDEX_OF_CHUNKS 1
-
-/* this allows indexing up to 64GB avi file */
-#define GST_AVI_SUPERINDEX_COUNT 32
-
-typedef struct _gst_avi_superindex_entry {
- guint64 offset;
- guint32 size;
- guint32 duration;
-} gst_avi_superindex_entry;
-
-typedef struct _gst_riff_strh_full {
- gst_riff_strh parent;
- /* rcFrame, RECT structure (struct of 4 shorts) */
- gint16 left;
- gint16 top;
- gint16 right;
- gint16 bottom;
-} gst_riff_strh_full;
-
-typedef struct _GstAviPad {
- /* do not extend, link to it */
- /* is NULL if original sink request pad has been removed */
- GstCollectData *collect;
-
- /* type */
- gboolean is_video;
- gboolean connected;
-
- /* chunk tag */
- gchar *tag;
-
- /* stream header */
- gst_riff_strh hdr;
-
- /* odml super indexes */
- gst_avi_superindex_entry idx[GST_AVI_SUPERINDEX_COUNT];
- gint idx_index;
- gchar *idx_tag;
-} GstAviPad;
-
-typedef struct _GstAviVideoPad {
- GstAviPad parent;
-
- /* stream format */
- gst_riff_strf_vids vids;
- /* extra data */
- GstBuffer *vids_codec_data;
- /* ODML video properties */
- gst_riff_vprp vprp;
-
-} GstAviVideoPad;
-
-typedef struct _GstAviAudioPad {
- GstAviPad parent;
-
- /* stream format */
- gst_riff_strf_auds auds;
- /* audio info for bps calculation */
- guint32 audio_size;
- guint64 audio_time;
- /* extra data */
- GstBuffer *auds_codec_data;
-} GstAviAudioPad;
-
-typedef struct _GstAviCollectData {
- /* extend the CollectData */
- GstCollectData collect;
-
- GstAviPad *avipad;
-} GstAviCollectData;
-
-typedef struct _GstAviMux GstAviMux;
-typedef struct _GstAviMuxClass GstAviMuxClass;
-
-struct _GstAviMux {
- GstElement element;
-
- /* pads */
- GstPad *srcpad;
- /* sinkpads, video first */
- GSList *sinkpads;
- /* video restricted to 1 pad */
- guint video_pads, audio_pads;
- GstCollectPads *collect;
- GstPadEventFunction collect_event;
-
- /* the AVI header */
- /* still some single stream video data in mux struct */
- gst_riff_avih avi_hdr;
- /* total number of (video) frames */
- guint32 total_frames;
- /* amount of total data (bytes) */
- guint64 total_data;
- /* amount of data (bytes) in the AVI/AVIX block;
- * actually the movi list, so counted from and including the movi tag */
- guint32 data_size, datax_size;
- /* num (video) frames in the AVI/AVIX block */
- guint32 num_frames, numx_frames;
- /* size of hdrl list, including tag as usual */
-
- /* total size of extra codec data */
- guint32 codec_data_size;
- /* state info */
- gboolean write_header;
- gboolean restart;
-
- /* tags */
- GstTagList *tags_snap;
-
- /* information about the AVI index ('idx') */
- gst_riff_index_entry *idx;
- gint idx_index, idx_count;
- /* offset of *chunk* (relative to a base offset); entered in the index */
- guint32 idx_offset;
- /* size of idx1 chunk (including! chunk header and size bytes) */
- guint32 idx_size;
-
- /* are we a big file already? */
- gboolean is_bigfile;
- guint64 avix_start;
-
- /* whether to use "large AVI files" or just stick to small indexed files */
- gboolean enable_large_avi;
-};
-
-struct _GstAviMuxClass {
- GstElementClass parent_class;
-};
-
-GType gst_avi_mux_get_type(void);
-
-G_END_DECLS
-
-
-#endif /* __GST_AVI_MUX_H__ */
--- a/gst_plugins_good/gst/avi/gstavisubtitle.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-/* GStreamer AVI GAB2 subtitle parser
- * Copyright (C) <2007> Thijs Vermeir <thijsvermeir@gmail.com>
- * Copyright (C) <2007> Tim-Philipp Müller <tim centricular net>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-avisubtitle
- *
- * <refsect2>
- * <para>
- * Parses the subtitle stream from an avi file.
- * </para>
- * <title>Example launch line</title>
- * <para>
- * <programlisting>
- * gst-launch filesrc location=subtitle.avi ! avidemux name=demux ! queue ! avisubtitle ! subparse ! textoverlay name=overlay ! ffmpegcolorspace ! autovideosink demux. ! queue ! decodebin ! overlay.
- * </programlisting>
- * This plays an avi file with a video and subtitle stream.
- * </para>
- * </refsect2>
- *
- * Last reviewed on 2008-02-01
- */
-
-/* example of a subtitle chunk in an avi file
- * 00000000: 47 41 42 32 00 02 00 10 00 00 00 45 00 6e 00 67 GAB2.......E.n.g
- * 00000010: 00 6c 00 69 00 73 00 68 00 00 00 04 00 8e 00 00 .l.i.s.h........
- * 00000020: 00 ef bb bf 31 0d 0a 30 30 3a 30 30 3a 30 30 2c ....1..00:00:00,
- * 00000030: 31 30 30 20 2d 2d 3e 20 30 30 3a 30 30 3a 30 32 100 --> 00:00:02
- * 00000040: 2c 30 30 30 0d 0a 3c 62 3e 41 6e 20 55 54 46 38 ,000..<b>An UTF8
- * 00000050: 20 53 75 62 74 69 74 6c 65 20 77 69 74 68 20 42 Subtitle with B
- * 00000060: 4f 4d 3c 2f 62 3e 0d 0a 0d 0a 32 0d 0a 30 30 3a OM</b>....2..00:
- * 00000070: 30 30 3a 30 32 2c 31 30 30 20 2d 2d 3e 20 30 30 00:02,100 --> 00
- * 00000080: 3a 30 30 3a 30 34 2c 30 30 30 0d 0a 53 6f 6d 65 :00:04,000..Some
- * 00000090: 74 68 69 6e 67 20 6e 6f 6e 41 53 43 49 49 20 2d thing nonASCII -
- * 000000a0: 20 c2 b5 c3 b6 c3 a4 c3 bc c3 9f 0d 0a 0d 0a ..............
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstavisubtitle.h"
-
-GST_DEBUG_CATEGORY_STATIC (avisubtitle_debug);
-#define GST_CAT_DEFAULT avisubtitle_debug
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-subtitle-avi")
- );
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-subtitle")
- );
-
-static void gst_avi_subtitle_title_tag (GstAviSubtitle * sub, gchar * title);
-static GstFlowReturn gst_avi_subtitle_chain (GstPad * pad, GstBuffer * buffer);
-static GstStateChangeReturn gst_avi_subtitle_change_state (GstElement * element,
- GstStateChange transition);
-static gboolean gst_avi_subtitle_send_event (GstElement * element,
- GstEvent * event);
-
-GST_BOILERPLATE (GstAviSubtitle, gst_avi_subtitle, GstElement,
- GST_TYPE_ELEMENT);
-
-#define IS_BOM_UTF8(data) ((GST_READ_UINT32_BE(data) >> 8) == 0xEFBBBF)
-#define IS_BOM_UTF16_BE(data) (GST_READ_UINT16_BE(data) == 0xFEFF)
-#define IS_BOM_UTF16_LE(data) (GST_READ_UINT16_LE(data) == 0xFEFF)
-#define IS_BOM_UTF32_BE(data) (GST_READ_UINT32_BE(data) == 0xFEFF)
-#define IS_BOM_UTF32_LE(data) (GST_READ_UINT32_LE(data) == 0xFEFF)
-
-static GstBuffer *
-gst_avi_subtitle_extract_file (GstAviSubtitle * sub, GstBuffer * buffer,
- guint offset, guint len)
-{
- const gchar *input_enc = NULL;
- GstBuffer *ret = NULL;
- gchar *data;
-
- data = (gchar *) GST_BUFFER_DATA (buffer) + offset;
-
- if (len >= (3 + 1) && IS_BOM_UTF8 (data) &&
- g_utf8_validate (data + 3, len - 3, NULL)) {
- ret = gst_buffer_create_sub (buffer, offset + 3, len - 3);
- } else if (len >= 2 && IS_BOM_UTF16_BE (data)) {
- input_enc = "UTF-16BE";
- data += 2;
- len -= 2;
- } else if (len >= 2 && IS_BOM_UTF16_LE (data)) {
- input_enc = "UTF-16LE";
- data += 2;
- len -= 2;
- } else if (len >= 4 && IS_BOM_UTF32_BE (data)) {
- input_enc = "UTF-32BE";
- data += 4;
- len -= 4;
- } else if (len >= 4 && IS_BOM_UTF32_LE (data)) {
- input_enc = "UTF-32LE";
- data += 4;
- len -= 4;
- } else if (g_utf8_validate (data, len, NULL)) {
- /* not specified, check if it's UTF-8 */
- ret = gst_buffer_create_sub (buffer, offset, len);
- } else {
- /* we could fall back to gst_tag_freeform_to_utf8() here */
- GST_WARNING_OBJECT (sub, "unspecified encoding, and not UTF-8");
- return NULL;
- }
-
- g_return_val_if_fail (ret != NULL || input_enc != NULL, NULL);
-
- if (input_enc) {
- GError *err = NULL;
- gchar *utf8;
-
- GST_DEBUG_OBJECT (sub, "converting subtitles from %s to UTF-8", input_enc);
- utf8 = g_convert (data, len, "UTF-8", input_enc, NULL, NULL, &err);
-
- if (err != NULL) {
- GST_WARNING_OBJECT (sub, "conversion to UTF-8 failed : %s", err->message);
- g_error_free (err);
- return NULL;
- }
-
- ret = gst_buffer_new ();
- GST_BUFFER_DATA (ret) = (guint8 *) utf8;
- GST_BUFFER_MALLOCDATA (ret) = (guint8 *) utf8;
- GST_BUFFER_SIZE (ret) = strlen (utf8);
- GST_BUFFER_OFFSET (ret) = 0;
- }
-
- GST_BUFFER_CAPS (ret) = gst_caps_new_simple ("application/x-subtitle", NULL);
- return ret;
-}
-
-/**
- * gst_avi_subtitle_title_tag:
- * @sub: subtitle element
- * @title: the title of this subtitle stream
- *
- * Send an event to the srcpad of the @sub element with the title
- * of the subtitle stream as a GST_TAG_TITLE
- */
-static void
-gst_avi_subtitle_title_tag (GstAviSubtitle * sub, gchar * title)
-{
- GstTagList *temp_list = gst_tag_list_new ();
-
- gst_tag_list_add (temp_list, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title,
- NULL);
- gst_pad_push_event (sub->src, gst_event_new_tag (temp_list));
-}
-
-static GstFlowReturn
-gst_avi_subtitle_parse_gab2_chunk (GstAviSubtitle * sub, GstBuffer * buf)
-{
- const guint8 *data;
- gchar *name_utf8;
- guint name_length;
- guint file_length;
- guint size;
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- /* check the magic word "GAB2\0", and the next word must be 2 */
- if (size < 12 || memcmp (data, "GAB2\0\2\0", 5 + 2) != 0)
- goto wrong_magic_word;
-
- /* read 'name' of subtitle */
- name_length = GST_READ_UINT32_LE (data + 5 + 2);
- GST_LOG_OBJECT (sub, "length of name: %u", name_length);
- if (size <= 17 + name_length)
- goto wrong_name_length;
-
- name_utf8 = g_convert ((gchar *) data + 11, name_length, "UTF-8", "UTF-16LE",
- NULL, NULL, NULL);
-
- if (name_utf8) {
- GST_LOG_OBJECT (sub, "subtitle name: %s", name_utf8);
- gst_avi_subtitle_title_tag (sub, name_utf8);
- g_free (name_utf8);
- }
-
- /* next word must be 4 */
- if (GST_READ_UINT16_LE (data + 11 + name_length) != 0x4)
- goto wrong_fixed_word_2;
-
- file_length = GST_READ_UINT32_LE (data + 13 + name_length);
- GST_LOG_OBJECT (sub, "length srt/ssa file: %u", file_length);
-
- if (size < (17 + name_length + file_length))
- goto wrong_total_length;
-
- /* store this, so we can send it again after a seek; note that we shouldn't
- * assume all the remaining data in the chunk is subtitle data, there may
- * be padding at the end for some reason, so only parse file_length bytes */
- sub->subfile =
- gst_avi_subtitle_extract_file (sub, buf, 17 + name_length, file_length);
-
- if (sub->subfile == NULL)
- goto extract_failed;
-
- return GST_FLOW_OK;
-
- /* ERRORS */
-wrong_magic_word:
- {
- GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL), ("Wrong magic word"));
- return GST_FLOW_ERROR;
- }
-wrong_name_length:
- {
- GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
- ("name doesn't fit in buffer (%d < %d)", size, 17 + name_length));
- return GST_FLOW_ERROR;
- }
-wrong_fixed_word_2:
- {
- GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
- ("wrong fixed word: expected %u, got %u", 4,
- GST_READ_UINT16_LE (data + 11 + name_length)));
- return GST_FLOW_ERROR;
- }
-wrong_total_length:
- {
- GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
- ("buffer size is wrong: need %d bytes, have %d bytes",
- 17 + name_length + file_length, size));
- return GST_FLOW_ERROR;
- }
-extract_failed:
- {
- GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
- ("could not extract subtitles"));
- return GST_FLOW_ERROR;
- }
-}
-
-static GstFlowReturn
-gst_avi_subtitle_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstAviSubtitle *sub = GST_AVI_SUBTITLE (GST_PAD_PARENT (pad));
- GstFlowReturn ret;
-
- if (sub->subfile != NULL) {
- GST_WARNING_OBJECT (sub, "Got more buffers than expected, dropping");
- ret = GST_FLOW_UNEXPECTED;
- goto done;
- }
-
- /* we expect exactly one buffer with the whole srt/ssa file in it */
- ret = gst_avi_subtitle_parse_gab2_chunk (sub, buffer);
- if (ret != GST_FLOW_OK)
- goto done;
-
- /* now push the subtitle data downstream */
- ret = gst_pad_push (sub->src, gst_buffer_ref (sub->subfile));
-
-done:
-
- gst_buffer_unref (buffer);
- return ret;
-}
-
-static gboolean
-gst_avi_subtitle_send_event (GstElement * element, GstEvent * event)
-{
- GstAviSubtitle *avisubtitle = GST_AVI_SUBTITLE (element);
- gboolean ret = FALSE;
-
- if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
- if (avisubtitle->subfile) {
- if (gst_pad_push (avisubtitle->src,
- gst_buffer_ref (avisubtitle->subfile)) == GST_FLOW_OK)
- ret = TRUE;
- }
- }
- gst_event_unref (event);
- return ret;
-}
-
-static void
-gst_avi_subtitle_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- GST_DEBUG_CATEGORY_INIT (avisubtitle_debug, "avisubtitle", 0,
- "parse avi subtitle stream");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
-
- gst_element_class_set_details_simple (element_class,
- "Avi subtitle parser", "Codec/Parser/Subtitle",
- "Parse avi subtitle stream", "Thijs Vermeir <thijsvermeir@gmail.com>");
-}
-
-static void
-gst_avi_subtitle_class_init (GstAviSubtitleClass * klass)
-{
- GstElementClass *gstelement_class = (GstElementClass *) klass;
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_avi_subtitle_change_state);
- gstelement_class->send_event =
- GST_DEBUG_FUNCPTR (gst_avi_subtitle_send_event);
-}
-
-static void
-gst_avi_subtitle_init (GstAviSubtitle * self, GstAviSubtitleClass * klass)
-{
- self->src = gst_pad_new_from_static_template (&src_template, "src");
- gst_element_add_pad (GST_ELEMENT (self), self->src);
-
- self->sink = gst_pad_new_from_static_template (&sink_template, "sink");
- gst_pad_set_chain_function (self->sink,
- GST_DEBUG_FUNCPTR (gst_avi_subtitle_chain));
- gst_element_add_pad (GST_ELEMENT (self), self->sink);
-
- self->subfile = NULL;
-}
-
-static GstStateChangeReturn
-gst_avi_subtitle_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstAviSubtitle *sub = GST_AVI_SUBTITLE (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (sub->subfile) {
- gst_buffer_unref (sub->subfile);
- sub->subfile = NULL;
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
--- a/gst_plugins_good/gst/avi/gstavisubtitle.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-
-#ifndef __GSTAVISUBTITLE_H__
-#define __GSTAVISUBTITLE_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GstAviSubtitle GstAviSubtitle;
-typedef struct _GstAviSubtitleClass GstAviSubtitleClass;
-
-#define GST_TYPE_AVI_SUBTITLE (gst_avi_subtitle_get_type ())
-#define GST_AVI_SUBTITLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AVI_SUBTITLE, GstAviSubtitle))
-#define GST_AVI_SUBTITLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AVI_SUBTITLE, GstAviSubtitleClass))
-#define GST_IS_AVI_SUBTITLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AVI_SUBTITLE))
-#define GST_IS_AVI_SUBTITLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AVI_SUBTITLE))
-#define GST_AVI_SUBTITLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AVI_SUBTITLE, GstAviSubtitleClass))
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_avi_subtitle_get_type (void);
-
-struct _GstAviSubtitle
-{
- GstElement parent;
-
- GstPad *src;
- GstPad *sink;
-
- GstBuffer *subfile; /* the complete subtitle file in one buffer */
-};
-
-struct _GstAviSubtitleClass
-{
- GstElementClass parent;
-};
-
-G_END_DECLS
-#endif
--- a/gst_plugins_good/gst/law/alaw-decode.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/* GStreamer A-Law to PCM conversion
- * Copyright (C) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- * 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.1 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/**
- * SECTION:element-alawdec
- *
- * This element decodes alaw audio. Alaw coding is also known as G.711.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "alaw-decode.h"
-
-extern GstStaticPadTemplate alaw_dec_src_factory;
-extern GstStaticPadTemplate alaw_dec_sink_factory;
-
-GST_DEBUG_CATEGORY_STATIC (alaw_dec_debug);
-#define GST_CAT_DEFAULT alaw_dec_debug
-
-static GstStateChangeReturn
-gst_alaw_dec_change_state (GstElement * element, GstStateChange transition);
-static GstFlowReturn gst_alaw_dec_chain (GstPad * pad, GstBuffer * buffer);
-
-GST_BOILERPLATE (GstALawDec, gst_alaw_dec, GstElement, GST_TYPE_ELEMENT);
-
-/* some day we might have defines in gstconfig.h that tell us about the
- * desired cpu/memory/binary size trade-offs */
-#define GST_ALAW_DEC_USE_TABLE
-
-#ifdef GST_ALAW_DEC_USE_TABLE
-
-static const gint alaw_to_s16_table[256] = {
- -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
- -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
- -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
- -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
- -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
- -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
- -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
- -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
- -344, -328, -376, -360, -280, -264, -312, -296,
- -472, -456, -504, -488, -408, -392, -440, -424,
- -88, -72, -120, -104, -24, -8, -56, -40,
- -216, -200, -248, -232, -152, -136, -184, -168,
- -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
- -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
- -688, -656, -752, -720, -560, -528, -624, -592,
- -944, -912, -1008, -976, -816, -784, -880, -848,
- 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
- 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
- 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
- 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
- 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
- 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
- 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
- 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
- 344, 328, 376, 360, 280, 264, 312, 296,
- 472, 456, 504, 488, 408, 392, 440, 424,
- 88, 72, 120, 104, 24, 8, 56, 40,
- 216, 200, 248, 232, 152, 136, 184, 168,
- 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
- 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
- 688, 656, 752, 720, 560, 528, 624, 592,
- 944, 912, 1008, 976, 816, 784, 880, 848
-};
-
-static inline gint
-alaw_to_s16 (guint8 a_val)
-{
- return alaw_to_s16_table[a_val];
-}
-
-#else /* GST_ALAW_DEC_USE_TABLE */
-
-static inline gint
-alaw_to_s16 (guint8 a_val)
-{
- gint t;
- gint seg;
-
- a_val ^= 0x55;
- t = a_val & 0x7f;
- if (t < 16)
- t = (t << 4) + 8;
- else {
- seg = (t >> 4) & 0x07;
- t = ((t & 0x0f) << 4) + 0x108;
- t <<= seg - 1;
- }
- return ((a_val & 0x80) ? t : -t);
-}
-
-#endif /* GST_ALAW_DEC_USE_TABLE */
-
-static gboolean
-gst_alaw_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstALawDec *alawdec;
- GstStructure *structure;
- int rate, channels;
- gboolean ret;
- GstCaps *outcaps;
-
- alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad));
-
- structure = gst_caps_get_structure (caps, 0);
-
- ret = gst_structure_get_int (structure, "rate", &rate);
- ret &= gst_structure_get_int (structure, "channels", &channels);
- if (!ret)
- return FALSE;
-
- outcaps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL);
-
- ret = gst_pad_set_caps (alawdec->srcpad, outcaps);
- gst_caps_unref (outcaps);
-
- if (ret) {
- GST_DEBUG_OBJECT (alawdec, "rate=%d, channels=%d", rate, channels);
- alawdec->rate = rate;
- alawdec->channels = channels;
- }
- return ret;
-}
-
-static GstCaps *
-gst_alaw_dec_getcaps (GstPad * pad)
-{
- GstALawDec *alawdec;
- GstPad *otherpad;
- GstCaps *othercaps, *result;
- const GstCaps *templ;
- gchar *name;
- gint i;
-
- alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad));
-
- /* figure out the name of the caps we are going to return */
- if (pad == alawdec->srcpad) {
- name = "audio/x-raw-int";
- otherpad = alawdec->sinkpad;
- } else {
- name = "audio/x-alaw";
- otherpad = alawdec->srcpad;
- }
- /* get caps from the peer, this can return NULL when there is no peer */
- othercaps = gst_pad_peer_get_caps (otherpad);
-
- /* get the template caps to make sure we return something acceptable */
- templ = gst_pad_get_pad_template_caps (pad);
-
- if (othercaps) {
- /* there was a peer */
- othercaps = gst_caps_make_writable (othercaps);
-
- /* go through the caps and remove the fields we don't want */
- for (i = 0; i < gst_caps_get_size (othercaps); i++) {
- GstStructure *structure;
-
- structure = gst_caps_get_structure (othercaps, i);
-
- /* adjust the name */
- gst_structure_set_name (structure, name);
-
- if (pad == alawdec->sinkpad) {
- /* remove the fields we don't want */
- gst_structure_remove_fields (structure, "width", "depth", "endianness",
- "signed", NULL);
- } else {
- /* add fixed fields */
- gst_structure_set (structure, "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- }
- }
- /* filter against the allowed caps of the pad to return our result */
- result = gst_caps_intersect (othercaps, templ);
- gst_caps_unref (othercaps);
- } else {
- /* there was no peer, return the template caps */
- result = gst_caps_copy (templ);
- }
-
- return result;
-}
-
-static void
-gst_alaw_dec_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&alaw_dec_src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&alaw_dec_sink_factory));
-
- gst_element_class_set_details_simple (element_class, "A Law audio decoder",
- "Codec/Decoder/Audio", "Convert 8bit A law to 16bit PCM",
- "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
-
- GST_DEBUG_CATEGORY_INIT (alaw_dec_debug, "alawdec", 0, "A Law audio decoder");
-}
-
-static void
-gst_alaw_dec_class_init (GstALawDecClass * klass)
-{
- GstElementClass *element_class = (GstElementClass *) klass;
-
- element_class->change_state = GST_DEBUG_FUNCPTR (gst_alaw_dec_change_state);
-}
-
-static void
-gst_alaw_dec_init (GstALawDec * alawdec, GstALawDecClass * klass)
-{
- alawdec->sinkpad =
- gst_pad_new_from_static_template (&alaw_dec_sink_factory, "sink");
- gst_pad_set_setcaps_function (alawdec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_dec_sink_setcaps));
- gst_pad_set_getcaps_function (alawdec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_dec_getcaps));
- gst_pad_set_chain_function (alawdec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_dec_chain));
- gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->sinkpad);
-
- alawdec->srcpad =
- gst_pad_new_from_static_template (&alaw_dec_src_factory, "src");
- gst_pad_use_fixed_caps (alawdec->srcpad);
- gst_pad_set_getcaps_function (alawdec->srcpad,
- GST_DEBUG_FUNCPTR (gst_alaw_dec_getcaps));
- gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->srcpad);
-}
-
-static GstFlowReturn
-gst_alaw_dec_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstALawDec *alawdec;
- gint16 *linear_data;
- guint8 *alaw_data;
- guint alaw_size;
- GstBuffer *outbuf;
- gint i;
- GstFlowReturn ret;
-
- alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad));
-
- if (G_UNLIKELY (alawdec->rate == 0))
- goto not_negotiated;
-
- GST_LOG_OBJECT (alawdec, "buffer with ts=%" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
-
- alaw_data = GST_BUFFER_DATA (buffer);
- alaw_size = GST_BUFFER_SIZE (buffer);
-
- ret =
- gst_pad_alloc_buffer_and_set_caps (alawdec->srcpad,
- GST_BUFFER_OFFSET_NONE, alaw_size * 2, GST_PAD_CAPS (alawdec->srcpad),
- &outbuf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
-
- linear_data = (gint16 *) GST_BUFFER_DATA (outbuf);
-
- /* copy discont flag */
- if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
-
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (alawdec->srcpad));
-
- for (i = 0; i < alaw_size; i++) {
- linear_data[i] = alaw_to_s16 (alaw_data[i]);
- }
- gst_buffer_unref (buffer);
-
- ret = gst_pad_push (alawdec->srcpad, outbuf);
-
- return ret;
-
-not_negotiated:
- {
- gst_buffer_unref (buffer);
- GST_WARNING_OBJECT (alawdec, "no input format set: not-negotiated");
- return GST_FLOW_NOT_NEGOTIATED;
- }
-alloc_failed:
- {
- gst_buffer_unref (buffer);
- GST_DEBUG_OBJECT (alawdec, "pad alloc failed, flow: %s",
- gst_flow_get_name (ret));
- return ret;
- }
-}
-
-static GstStateChangeReturn
-gst_alaw_dec_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstALawDec *dec = GST_ALAW_DEC (element);
-
- switch (transition) {
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret != GST_STATE_CHANGE_SUCCESS)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- dec->rate = 0;
- dec->channels = 0;
- break;
- default:
- break;
- }
-
- return ret;
-}
--- a/gst_plugins_good/gst/law/alaw-decode.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* GStreamer A-Law to PCM conversion
- * Copyright (C) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_ALAW_DECODE_H__
-#define __GST_ALAW_DECODE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_ALAW_DEC \
- (gst_alaw_dec_get_type())
-#define GST_ALAW_DEC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALAW_DEC,GstALawDec))
-#define GST_ALAW_DEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALAW_DEC,GstALawDecClass))
-#define GST_IS_ALAW_DEC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALAW_DEC))
-#define GST_IS_ALAW_DEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALAW_DEC))
-
-typedef struct _GstALawDec GstALawDec;
-typedef struct _GstALawDecClass GstALawDecClass;
-
-struct _GstALawDec {
- GstElement element;
-
- GstPad *sinkpad,*srcpad;
- gint rate;
- gint channels;
-};
-
-struct _GstALawDecClass {
- GstElementClass parent_class;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-
-GType gst_alaw_dec_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_ALAW_DECODE_H__ */
-
--- a/gst_plugins_good/gst/law/alaw-encode.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,524 +0,0 @@
-/* GStreamer PCM to A-Law conversion
- * Copyright (C) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- * 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.1 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/**
- * SECTION:element-alawenc
- *
- * This element encode alaw audio. Alaw coding is also known as G.711.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "alaw-encode.h"
-
-GST_DEBUG_CATEGORY_STATIC (alaw_enc_debug);
-#define GST_CAT_DEFAULT alaw_enc_debug
-
-extern GstStaticPadTemplate alaw_enc_src_factory;
-extern GstStaticPadTemplate alaw_enc_sink_factory;
-
-static GstFlowReturn gst_alaw_enc_chain (GstPad * pad, GstBuffer * buffer);
-
-GST_BOILERPLATE (GstALawEnc, gst_alaw_enc, GstElement, GST_TYPE_ELEMENT);
-
-/* some day we might have defines in gstconfig.h that tell us about the
- * desired cpu/memory/binary size trade-offs */
-#define GST_ALAW_ENC_USE_TABLE
-
-#ifdef GST_ALAW_ENC_USE_TABLE
-
-static const guint8 alaw_encode[2048 + 1] = {
- 0xd5, 0xd4, 0xd7, 0xd6, 0xd1, 0xd0, 0xd3, 0xd2, 0xdd, 0xdc, 0xdf, 0xde,
- 0xd9, 0xd8, 0xdb, 0xda, 0xc5, 0xc4, 0xc7, 0xc6, 0xc1, 0xc0, 0xc3, 0xc2,
- 0xcd, 0xcc, 0xcf, 0xce, 0xc9, 0xc8, 0xcb, 0xca, 0xf5, 0xf5, 0xf4, 0xf4,
- 0xf7, 0xf7, 0xf6, 0xf6, 0xf1, 0xf1, 0xf0, 0xf0, 0xf3, 0xf3, 0xf2, 0xf2,
- 0xfd, 0xfd, 0xfc, 0xfc, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xf9, 0xf8, 0xf8,
- 0xfb, 0xfb, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef,
- 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a
-};
-
-static inline guint8
-s16_to_alaw (gint16 pcm_val)
-{
- if (pcm_val >= 0)
- return alaw_encode[pcm_val / 16];
- else
- return (0x7F & alaw_encode[pcm_val / -16]);
-}
-
-#else /* GST_ALAW_ENC_USE_TABLE */
-
-/*
- * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
- *
- * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
- *
- * Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 0000000wxyza 000wxyz
- * 0000001wxyza 001wxyz
- * 000001wxyzab 010wxyz
- * 00001wxyzabc 011wxyz
- * 0001wxyzabcd 100wxyz
- * 001wxyzabcde 101wxyz
- * 01wxyzabcdef 110wxyz
- * 1wxyzabcdefg 111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-
-static inline gint
-val_seg (gint val)
-{
- gint r = 1;
-
- val >>= 8;
- if (val & 0xf0) {
- val >>= 4;
- r += 4;
- }
- if (val & 0x0c) {
- val >>= 2;
- r += 2;
- }
- if (val & 0x02)
- r += 1;
- return r;
-}
-
-static inline guint8
-s16_to_alaw (gint pcm_val)
-{
- gint seg;
- guint8 mask;
- guint8 aval;
-
- if (pcm_val >= 0) {
- mask = 0xD5;
- } else {
- mask = 0x55;
- pcm_val = -pcm_val;
- if (pcm_val > 0x7fff)
- pcm_val = 0x7fff;
- }
-
- if (pcm_val < 256)
- aval = pcm_val >> 4;
- else {
- /* Convert the scaled magnitude to segment number. */
- seg = val_seg (pcm_val);
- aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
- }
- return aval ^ mask;
-}
-
-#endif /* GST_ALAW_ENC_USE_TABLE */
-
-static GstCaps *
-gst_alaw_enc_getcaps (GstPad * pad)
-{
- GstALawEnc *alawenc;
- GstPad *otherpad;
- GstCaps *othercaps, *result;
- const GstCaps *templ;
- gchar *name;
- gint i;
-
- alawenc = GST_ALAW_ENC (GST_PAD_PARENT (pad));
-
- /* figure out the name of the caps we are going to return */
- if (pad == alawenc->srcpad) {
- name = "audio/x-alaw";
- otherpad = alawenc->sinkpad;
- } else {
- name = "audio/x-raw-int";
- otherpad = alawenc->srcpad;
- }
- /* get caps from the peer, this can return NULL when there is no peer */
- othercaps = gst_pad_peer_get_caps (otherpad);
-
- /* get the template caps to make sure we return something acceptable */
- templ = gst_pad_get_pad_template_caps (pad);
-
- if (othercaps) {
- /* there was a peer */
- othercaps = gst_caps_make_writable (othercaps);
-
- /* go through the caps and remove the fields we don't want */
- for (i = 0; i < gst_caps_get_size (othercaps); i++) {
- GstStructure *structure;
-
- structure = gst_caps_get_structure (othercaps, i);
-
- /* adjust the name */
- gst_structure_set_name (structure, name);
-
- if (pad == alawenc->srcpad) {
- /* remove the fields we don't want */
- gst_structure_remove_fields (structure, "width", "depth", "endianness",
- "signed", NULL);
- } else {
- /* add fixed fields */
- gst_structure_set (structure, "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- }
- }
- /* filter against the allowed caps of the pad to return our result */
- result = gst_caps_intersect (othercaps, templ);
- gst_caps_unref (othercaps);
- } else {
- /* there was no peer, return the template caps */
- result = gst_caps_copy (templ);
- }
-
- return result;
-}
-
-static gboolean
-gst_alaw_enc_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstALawEnc *alawenc;
- GstPad *otherpad;
- GstStructure *structure;
- gboolean ret;
- GstCaps *base_caps;
-
- alawenc = GST_ALAW_ENC (GST_PAD_PARENT (pad));
-
- structure = gst_caps_get_structure (caps, 0);
- gst_structure_get_int (structure, "channels", &alawenc->channels);
- gst_structure_get_int (structure, "rate", &alawenc->rate);
-
- if (pad == alawenc->sinkpad) {
- otherpad = alawenc->srcpad;
- } else {
- otherpad = alawenc->sinkpad;
- }
-
- base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
- structure = gst_caps_get_structure (base_caps, 0);
- gst_structure_set (structure, "rate", G_TYPE_INT, alawenc->rate, NULL);
- gst_structure_set (structure, "channels", G_TYPE_INT, alawenc->channels,
- NULL);
-
- GST_DEBUG_OBJECT (alawenc, "rate=%d, channels=%d", alawenc->rate,
- alawenc->channels);
-
- ret = gst_pad_set_caps (otherpad, base_caps);
-
- gst_caps_unref (base_caps);
-
- return ret;
-}
-
-static void
-gst_alaw_enc_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&alaw_enc_src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&alaw_enc_sink_factory));
-
- gst_element_class_set_details_simple (element_class,
- "A Law audio encoder", "Codec/Encoder/Audio",
- "Convert 16bit PCM to 8bit A law",
- "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
-
- GST_DEBUG_CATEGORY_INIT (alaw_enc_debug, "alawenc", 0, "A Law audio encoder");
-}
-
-static void
-gst_alaw_enc_class_init (GstALawEncClass * klass)
-{
- /* nothing to do here for now */
-}
-
-static void
-gst_alaw_enc_init (GstALawEnc * alawenc, GstALawEncClass * klass)
-{
- alawenc->sinkpad =
- gst_pad_new_from_static_template (&alaw_enc_sink_factory, "sink");
- gst_pad_set_setcaps_function (alawenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_enc_setcaps));
- gst_pad_set_getcaps_function (alawenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_enc_getcaps));
- gst_pad_set_chain_function (alawenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_alaw_enc_chain));
- gst_element_add_pad (GST_ELEMENT (alawenc), alawenc->sinkpad);
-
- alawenc->srcpad =
- gst_pad_new_from_static_template (&alaw_enc_src_factory, "src");
- gst_pad_set_setcaps_function (alawenc->srcpad,
- GST_DEBUG_FUNCPTR (gst_alaw_enc_setcaps));
- gst_pad_set_getcaps_function (alawenc->srcpad,
- GST_DEBUG_FUNCPTR (gst_alaw_enc_getcaps));
- gst_pad_use_fixed_caps (alawenc->srcpad);
- gst_element_add_pad (GST_ELEMENT (alawenc), alawenc->srcpad);
-
- /* init rest */
- alawenc->channels = 0;
- alawenc->rate = 0;
-}
-
-static GstFlowReturn
-gst_alaw_enc_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstALawEnc *alawenc;
- gint16 *linear_data;
- guint linear_size;
- guint8 *alaw_data;
- guint alaw_size;
- GstBuffer *outbuf;
- gint i;
- GstFlowReturn ret;
- GstClockTime timestamp, duration;
-
- alawenc = GST_ALAW_ENC (GST_PAD_PARENT (pad));
-
- if (G_UNLIKELY (alawenc->rate == 0 || alawenc->channels == 0))
- goto not_negotiated;
-
- linear_data = (gint16 *) GST_BUFFER_DATA (buffer);
- linear_size = GST_BUFFER_SIZE (buffer);
-
- alaw_size = linear_size / 2;
-
- timestamp = GST_BUFFER_TIMESTAMP (buffer);
- duration = GST_BUFFER_DURATION (buffer);
-
- GST_LOG_OBJECT (alawenc, "buffer with ts=%" GST_TIME_FORMAT,
- GST_TIME_ARGS (timestamp));
-
- ret =
- gst_pad_alloc_buffer_and_set_caps (alawenc->srcpad,
- GST_BUFFER_OFFSET_NONE, alaw_size, GST_PAD_CAPS (alawenc->srcpad),
- &outbuf);
- if (ret != GST_FLOW_OK)
- goto done;
-
- if (duration == GST_CLOCK_TIME_NONE) {
- duration = gst_util_uint64_scale_int (alaw_size,
- GST_SECOND, alawenc->rate * alawenc->channels);
- }
-
- if (GST_BUFFER_SIZE (outbuf) < alaw_size) {
- /* pad-alloc can return a smaller buffer */
- gst_buffer_unref (outbuf);
- outbuf = gst_buffer_new_and_alloc (alaw_size);
- }
-
- alaw_data = (guint8 *) GST_BUFFER_DATA (outbuf);
-
- /* copy discont flag */
- if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
-
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- GST_BUFFER_DURATION (outbuf) = duration;
-
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (alawenc->srcpad));
-
- for (i = 0; i < alaw_size; i++) {
- alaw_data[i] = s16_to_alaw (linear_data[i]);
- }
-
- ret = gst_pad_push (alawenc->srcpad, outbuf);
-
-done:
-
- gst_buffer_unref (buffer);
-
- return ret;
-
-not_negotiated:
- {
- ret = GST_FLOW_NOT_NEGOTIATED;
- goto done;
- }
-}
--- a/gst_plugins_good/gst/law/alaw-encode.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* GStreamer PCM to A-Law conversion
- * Copyright (C) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_ALAW_ENCODE_H__
-#define __GST_ALAW_ENCODE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_ALAW_ENC \
- (gst_alaw_enc_get_type())
-#define GST_ALAW_ENC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALAW_ENC,GstALawEnc))
-#define GST_ALAW_ENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALAW_ENC,GstALawEncClass))
-#define GST_IS_ALAW_ENC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALAW_ENC))
-#define GST_IS_ALAW_ENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALAW_ENC))
-
-typedef struct _GstALawEnc GstALawEnc;
-typedef struct _GstALawEncClass GstALawEncClass;
-
-struct _GstALawEnc {
- GstElement element;
-
- GstPad *sinkpad,*srcpad;
-
- gint channels;
- gint rate;
-};
-
-struct _GstALawEncClass {
- GstElementClass parent_class;
-};
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-
-GType gst_alaw_enc_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_ALAW_ENCODE_H__ */
--- a/gst_plugins_good/gst/law/alaw.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/* GStreamer PCM/A-Law conversions
- *
- * 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.1 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "alaw-encode.h"
-#include "alaw-decode.h"
-
-GstStaticPadTemplate alaw_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "rate = (int) [ 8000, 192000 ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
- );
-
-GstStaticPadTemplate alaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-alaw, "
- "rate = [ 8000 , 192000 ], " "channels = [ 1 , 2 ]")
- );
-
-GstStaticPadTemplate alaw_enc_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "rate = (int) [ 8000, 192000 ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
- );
-
-GstStaticPadTemplate alaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-alaw, "
- "rate = [ 8000 , 192000 ], " "channels = [ 1 , 2 ]")
- );
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "alawenc",
- GST_RANK_NONE, GST_TYPE_ALAW_ENC) ||
- !gst_element_register (plugin, "alawdec",
- GST_RANK_PRIMARY, GST_TYPE_ALAW_DEC))
- return FALSE;
-
- return TRUE;
-}
-
-/* FIXME 0.11: merge alaw and mulaw into one plugin? */
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "alaw",
- "ALaw audio conversion routines",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
--- a/gst_plugins_good/gst/law/mulaw-conversion.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * This routine converts from linear to ulaw
- * 29 September 1989
- *
- * Craig Reese: IDA/Supercomputing Research Center
- * Joe Campbell: Department of Defense
- *
- * References:
- * 1) CCITT Recommendation G.711 (very difficult to follow)
- * 2) "A New Digital Technique for Implementation of Any
- * Continuous PCM Companding Law," Villeret, Michel,
- * et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
- * 1973, pg. 11.12-11.17
- * 3) MIL-STD-188-113,"Interoperability and Performance Standards
- * for Analog-to_Digital Conversion Techniques,"
- * 17 February 1987
- *
- * Input: Signed 16 bit linear sample
- * Output: 8 bit ulaw sample
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib.h>
-
-#undef ZEROTRAP /* turn on the trap as per the MIL-STD */
-#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
-#define CLIP 32635
-
-void
-mulaw_encode (gint16 * in, guint8 * out, gint numsamples)
-{
- static gint16 exp_lut[256] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- };
- gint16 sign, exponent, mantissa, i;
- gint16 sample;
- guint8 ulawbyte;
-
- for (i = 0; i < numsamples; i++) {
- sample = in[i];
- /** get the sample into sign-magnitude **/
- sign = (sample >> 8) & 0x80; /* set aside the sign */
- if (sign != 0) {
- sample = -sample; /* get magnitude */
- }
- /* sample can be zero because we can overflow in the inversion,
- * checking against the unsigned version solves this */
- if (((guint16) sample) > CLIP)
- sample = CLIP; /* clip the magnitude */
-
- /** convert from 16 bit linear to ulaw **/
- sample = sample + BIAS;
- exponent = exp_lut[(sample >> 7) & 0xFF];
- mantissa = (sample >> (exponent + 3)) & 0x0F;
- ulawbyte = ~(sign | (exponent << 4) | mantissa);
-#ifdef ZEROTRAP
- if (ulawbyte == 0)
- ulawbyte = 0x02; /* optional CCITT trap */
-#endif
- out[i] = ulawbyte;
- }
-}
-
-/*
- * This routine converts from ulaw to 16 bit linear
- * 29 September 1989
- *
- * Craig Reese: IDA/Supercomputing Research Center
- *
- * References:
- * 1) CCITT Recommendation G.711 (very difficult to follow)
- * 2) MIL-STD-188-113,"Interoperability and Performance Standards
- * for Analog-to_Digital Conversion Techniques,"
- * 17 February 1987
- *
- * Input: 8 bit ulaw sample
- * Output: signed 16 bit linear sample
- */
-
-void
-mulaw_decode (guint8 * in, gint16 * out, gint numsamples)
-{
- static gint16 exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
- gint16 sign, exponent, mantissa;
- guint8 ulawbyte;
- gint16 linear, i;
-
- for (i = 0; i < numsamples; i++) {
- ulawbyte = in[i];
- ulawbyte = ~ulawbyte;
- sign = (ulawbyte & 0x80);
- exponent = (ulawbyte >> 4) & 0x07;
- mantissa = ulawbyte & 0x0F;
- linear = exp_lut[exponent] + (mantissa << (exponent + 3));
- if (sign != 0)
- linear = -linear;
- out[i] = linear;
- }
-}
--- a/gst_plugins_good/gst/law/mulaw-conversion.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#ifndef _GST_ULAW_CONVERSION_H
-#define _GST_ULAW_CONVERSION_H
-
-#include <glib.h>
-
-void
-mulaw_encode(gint16* in, guint8* out, gint numsamples);
-void
-mulaw_decode(guint8* in,gint16* out,gint numsamples);
-
-#endif /* _GST_ULAW_CONVERSION_H */
-
--- a/gst_plugins_good/gst/law/mulaw-decode.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/**
- * SECTION:element-mulawdec
- *
- * This element decodes mulaw audio. Mulaw coding is also known as G.711.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <gst/gst.h>
-#include "mulaw-decode.h"
-#include "mulaw-conversion.h"
-
-extern GstStaticPadTemplate mulaw_dec_src_factory;
-extern GstStaticPadTemplate mulaw_dec_sink_factory;
-
-/* Stereo signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0
-};
-
-static void gst_mulawdec_class_init (GstMuLawDecClass * klass);
-static void gst_mulawdec_base_init (GstMuLawDecClass * klass);
-static void gst_mulawdec_init (GstMuLawDec * mulawdec);
-static GstStateChangeReturn
-gst_mulawdec_change_state (GstElement * element, GstStateChange transition);
-
-static GstFlowReturn gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer);
-
-static GstElementClass *parent_class = NULL;
-
-static gboolean
-mulawdec_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstMuLawDec *mulawdec;
- GstStructure *structure;
- int rate, channels;
- gboolean ret;
- GstCaps *outcaps;
-
- mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
-
- structure = gst_caps_get_structure (caps, 0);
- ret = gst_structure_get_int (structure, "rate", &rate);
- ret = ret && gst_structure_get_int (structure, "channels", &channels);
- if (!ret)
- return FALSE;
-
- outcaps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL);
- ret = gst_pad_set_caps (mulawdec->srcpad, outcaps);
- gst_caps_unref (outcaps);
-
- if (ret) {
- GST_DEBUG_OBJECT (mulawdec, "rate=%d, channels=%d", rate, channels);
- mulawdec->rate = rate;
- mulawdec->channels = channels;
- }
- return ret;
-}
-
-static GstCaps *
-mulawdec_getcaps (GstPad * pad)
-{
- GstMuLawDec *mulawdec;
- GstPad *otherpad;
- GstCaps *othercaps, *result;
- const GstCaps *templ;
- gchar *name;
- gint i;
-
- mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
-
- /* figure out the name of the caps we are going to return */
- if (pad == mulawdec->srcpad) {
- name = "audio/x-raw-int";
- otherpad = mulawdec->sinkpad;
- } else {
- name = "audio/x-mulaw";
- otherpad = mulawdec->srcpad;
- }
- /* get caps from the peer, this can return NULL when there is no peer */
- othercaps = gst_pad_peer_get_caps (otherpad);
-
- /* get the template caps to make sure we return something acceptable */
- templ = gst_pad_get_pad_template_caps (pad);
-
- if (othercaps) {
- /* there was a peer */
- othercaps = gst_caps_make_writable (othercaps);
-
- /* go through the caps and remove the fields we don't want */
- for (i = 0; i < gst_caps_get_size (othercaps); i++) {
- GstStructure *structure;
-
- structure = gst_caps_get_structure (othercaps, i);
-
- /* adjust the name */
- gst_structure_set_name (structure, name);
-
- if (pad == mulawdec->sinkpad) {
- /* remove the fields we don't want */
- gst_structure_remove_fields (structure, "width", "depth", "endianness",
- "signed", NULL);
- } else {
- /* add fixed fields */
- gst_structure_set (structure, "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- }
- }
- /* filter against the allowed caps of the pad to return our result */
- result = gst_caps_intersect (othercaps, templ);
- gst_caps_unref (othercaps);
- } else {
- /* there was no peer, return the template caps */
- result = gst_caps_copy (templ);
- }
- return result;
-}
-
-GType
-gst_mulawdec_get_type (void)
-{
- static GType mulawdec_type = 0;
-
- if (!mulawdec_type) {
- static const GTypeInfo mulawdec_info = {
- sizeof (GstMuLawDecClass),
- (GBaseInitFunc) gst_mulawdec_base_init,
- NULL,
- (GClassInitFunc) gst_mulawdec_class_init,
- NULL,
- NULL,
- sizeof (GstMuLawDec),
- 0,
- (GInstanceInitFunc) gst_mulawdec_init,
- };
-
- mulawdec_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstMuLawDec", &mulawdec_info,
- 0);
- }
- return mulawdec_type;
-}
-
-static void
-gst_mulawdec_base_init (GstMuLawDecClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- const GstElementDetails mulawdec_details =
- GST_ELEMENT_DETAILS ("Mu Law audio decoder",
- "Codec/Decoder/Audio",
- "Convert 8bit mu law to 16bit PCM",
- "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mulaw_dec_src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mulaw_dec_sink_factory));
- gst_element_class_set_details (element_class, &mulawdec_details);
-}
-
-static void
-gst_mulawdec_class_init (GstMuLawDecClass * klass)
-{
- GstElementClass *element_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- element_class->change_state = GST_DEBUG_FUNCPTR (gst_mulawdec_change_state);
-}
-
-static void
-gst_mulawdec_init (GstMuLawDec * mulawdec)
-{
- mulawdec->sinkpad =
- gst_pad_new_from_static_template (&mulaw_dec_sink_factory, "sink");
- gst_pad_set_setcaps_function (mulawdec->sinkpad, mulawdec_sink_setcaps);
- gst_pad_set_getcaps_function (mulawdec->sinkpad, mulawdec_getcaps);
- gst_pad_set_chain_function (mulawdec->sinkpad, gst_mulawdec_chain);
- gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->sinkpad);
-
- mulawdec->srcpad =
- gst_pad_new_from_static_template (&mulaw_dec_src_factory, "src");
- gst_pad_use_fixed_caps (mulawdec->srcpad);
- gst_pad_set_getcaps_function (mulawdec->srcpad, mulawdec_getcaps);
- gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->srcpad);
-}
-
-static GstFlowReturn
-gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstMuLawDec *mulawdec;
- gint16 *linear_data;
- guint8 *mulaw_data;
- guint mulaw_size;
- GstBuffer *outbuf;
- GstFlowReturn ret;
-
- mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
-
- if (G_UNLIKELY (mulawdec->rate == 0))
- goto not_negotiated;
-
- mulaw_data = (guint8 *) GST_BUFFER_DATA (buffer);
- mulaw_size = GST_BUFFER_SIZE (buffer);
-
- ret =
- gst_pad_alloc_buffer_and_set_caps (mulawdec->srcpad,
- GST_BUFFER_OFFSET_NONE, mulaw_size * 2, GST_PAD_CAPS (mulawdec->srcpad),
- &outbuf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
-
- linear_data = (gint16 *) GST_BUFFER_DATA (outbuf);
-
- /* copy discont flag */
- if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
-
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
- if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
- GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale_int (GST_SECOND,
- mulaw_size * 2, 2 * mulawdec->rate * mulawdec->channels);
- else
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawdec->srcpad));
-
- mulaw_decode (mulaw_data, linear_data, mulaw_size);
-
- gst_buffer_unref (buffer);
-
- ret = gst_pad_push (mulawdec->srcpad, outbuf);
-
- return ret;
-
- /* ERRORS */
-not_negotiated:
- {
- GST_WARNING_OBJECT (mulawdec, "no input format set: not-negotiated");
- gst_buffer_unref (buffer);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-alloc_failed:
- {
- GST_DEBUG_OBJECT (mulawdec, "pad alloc failed, flow: %s",
- gst_flow_get_name (ret));
- gst_buffer_unref (buffer);
- return ret;
- }
-}
-
-static GstStateChangeReturn
-gst_mulawdec_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret;
- GstMuLawDec *dec = GST_MULAWDEC (element);
-
- switch (transition) {
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret != GST_STATE_CHANGE_SUCCESS)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- dec->rate = 0;
- dec->channels = 0;
- break;
- default:
- break;
- }
-
- return ret;
-}
--- a/gst_plugins_good/gst/law/mulaw-decode.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_MULAWDECODE_H__
-#define __GST_MULAWDECODE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_MULAWDEC \
- (gst_mulawdec_get_type())
-#define GST_MULAWDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MULAWDEC,GstMuLawDec))
-#define GST_MULAWDEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MULAWDEC,GstMuLawDecClass))
-#define GST_IS_MULAWDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULAWDEC))
-#define GST_IS_MULAWDEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULAWDEC))
-
-typedef struct _GstMuLawDec GstMuLawDec;
-typedef struct _GstMuLawDecClass GstMuLawDecClass;
-
-struct _GstMuLawDec {
- GstElement element;
-
- GstPad *sinkpad,*srcpad;
-
- gint rate;
- gint channels;
-};
-
-struct _GstMuLawDecClass {
- GstElementClass parent_class;
-};
-
-GType gst_mulawdec_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_STEREO_H__ */
--- a/gst_plugins_good/gst/law/mulaw-encode.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/**
- * SECTION:element-mulawenc
- *
- * This element encode mulaw audio. Mulaw coding is also known as G.711.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <gst/gst.h>
-#include "mulaw-encode.h"
-#include "mulaw-conversion.h"
-
-extern GstStaticPadTemplate mulaw_enc_src_factory;
-extern GstStaticPadTemplate mulaw_enc_sink_factory;
-
-/* Stereo signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0
-};
-
-static void gst_mulawenc_class_init (GstMuLawEncClass * klass);
-static void gst_mulawenc_base_init (GstMuLawEncClass * klass);
-static void gst_mulawenc_init (GstMuLawEnc * mulawenc);
-
-static GstFlowReturn gst_mulawenc_chain (GstPad * pad, GstBuffer * buffer);
-
-static GstElementClass *parent_class = NULL;
-
-/*static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; */
-
-static GstCaps *
-mulawenc_getcaps (GstPad * pad)
-{
- GstMuLawEnc *mulawenc;
- GstPad *otherpad;
- GstCaps *othercaps, *result;
- const GstCaps *templ;
- gchar *name;
- gint i;
-
- mulawenc = GST_MULAWENC (GST_PAD_PARENT (pad));
-
- /* figure out the name of the caps we are going to return */
- if (pad == mulawenc->srcpad) {
- name = "audio/x-mulaw";
- otherpad = mulawenc->sinkpad;
- } else {
- name = "audio/x-raw-int";
- otherpad = mulawenc->srcpad;
- }
- /* get caps from the peer, this can return NULL when there is no peer */
- othercaps = gst_pad_peer_get_caps (otherpad);
-
- /* get the template caps to make sure we return something acceptable */
- templ = gst_pad_get_pad_template_caps (pad);
-
- if (othercaps) {
- /* there was a peer */
- othercaps = gst_caps_make_writable (othercaps);
-
- /* go through the caps and remove the fields we don't want */
- for (i = 0; i < gst_caps_get_size (othercaps); i++) {
- GstStructure *structure;
-
- structure = gst_caps_get_structure (othercaps, i);
-
- /* adjust the name */
- gst_structure_set_name (structure, name);
-
- if (pad == mulawenc->srcpad) {
- /* remove the fields we don't want */
- gst_structure_remove_fields (structure, "width", "depth", "endianness",
- "signed", NULL);
- } else {
- /* add fixed fields */
- gst_structure_set (structure, "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- }
- }
- /* filter against the allowed caps of the pad to return our result */
- result = gst_caps_intersect (othercaps, templ);
- gst_caps_unref (othercaps);
- } else {
- /* there was no peer, return the template caps */
- result = gst_caps_copy (templ);
- }
- return result;
-}
-
-static gboolean
-mulawenc_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstMuLawEnc *mulawenc;
- GstPad *otherpad;
- GstStructure *structure;
- GstCaps *base_caps;
-
- mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
-
- structure = gst_caps_get_structure (caps, 0);
- gst_structure_get_int (structure, "channels", &mulawenc->channels);
- gst_structure_get_int (structure, "rate", &mulawenc->rate);
-
- if (pad == mulawenc->sinkpad) {
- otherpad = mulawenc->srcpad;
- } else {
- otherpad = mulawenc->sinkpad;
- }
- base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
-
- structure = gst_caps_get_structure (base_caps, 0);
- gst_structure_set (structure, "rate", G_TYPE_INT, mulawenc->rate, NULL);
- gst_structure_set (structure, "channels", G_TYPE_INT, mulawenc->channels,
- NULL);
-
- gst_pad_set_caps (otherpad, base_caps);
-
- gst_object_unref (mulawenc);
- gst_caps_unref (base_caps);
-
- return TRUE;
-}
-
-GType
-gst_mulawenc_get_type (void)
-{
- static GType mulawenc_type = 0;
-
- if (!mulawenc_type) {
- static const GTypeInfo mulawenc_info = {
- sizeof (GstMuLawEncClass),
- (GBaseInitFunc) gst_mulawenc_base_init,
- NULL,
- (GClassInitFunc) gst_mulawenc_class_init,
- NULL,
- NULL,
- sizeof (GstMuLawEnc),
- 0,
- (GInstanceInitFunc) gst_mulawenc_init,
- };
-
- mulawenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstMuLawEnc", &mulawenc_info,
- 0);
- }
- return mulawenc_type;
-}
-
-static void
-gst_mulawenc_base_init (GstMuLawEncClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
- const GstElementDetails mulawenc_details =
- GST_ELEMENT_DETAILS ("Mu Law audio encoder",
- "Codec/Encoder/Audio",
- "Convert 16bit PCM to 8bit mu law",
- "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mulaw_enc_src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mulaw_enc_sink_factory));
- gst_element_class_set_details (element_class, &mulawenc_details);
-}
-
-static void
-gst_mulawenc_class_init (GstMuLawEncClass * klass)
-{
- parent_class = g_type_class_peek_parent (klass);
-}
-
-static void
-gst_mulawenc_init (GstMuLawEnc * mulawenc)
-{
- mulawenc->sinkpad =
- gst_pad_new_from_static_template (&mulaw_enc_sink_factory, "sink");
- gst_pad_set_setcaps_function (mulawenc->sinkpad, mulawenc_setcaps);
- gst_pad_set_getcaps_function (mulawenc->sinkpad, mulawenc_getcaps);
- gst_pad_set_chain_function (mulawenc->sinkpad, gst_mulawenc_chain);
- gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->sinkpad);
-
- mulawenc->srcpad =
- gst_pad_new_from_static_template (&mulaw_enc_src_factory, "src");
- gst_pad_set_setcaps_function (mulawenc->srcpad, mulawenc_setcaps);
- gst_pad_set_getcaps_function (mulawenc->srcpad, mulawenc_getcaps);
- gst_pad_use_fixed_caps (mulawenc->srcpad);
- gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->srcpad);
-
- /* init rest */
- mulawenc->channels = 0;
- mulawenc->rate = 0;
-}
-
-static GstFlowReturn
-gst_mulawenc_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstMuLawEnc *mulawenc;
- gint16 *linear_data;
- guint linear_size;
- guint8 *mulaw_data;
- guint mulaw_size;
- GstBuffer *outbuf;
- GstFlowReturn ret;
- GstClockTime timestamp, duration;
-
- mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
-
- if (!mulawenc->rate || !mulawenc->channels)
- goto not_negotiated;
-
- linear_data = (gint16 *) GST_BUFFER_DATA (buffer);
- linear_size = GST_BUFFER_SIZE (buffer);
-
- mulaw_size = linear_size / 2;
-
- timestamp = GST_BUFFER_TIMESTAMP (buffer);
- duration = GST_BUFFER_DURATION (buffer);
-
- ret = gst_pad_alloc_buffer_and_set_caps (mulawenc->srcpad,
- GST_BUFFER_OFFSET_NONE, mulaw_size, GST_PAD_CAPS (mulawenc->srcpad),
- &outbuf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
-
- if (duration == -1) {
- duration = gst_util_uint64_scale_int (mulaw_size,
- GST_SECOND, mulawenc->rate * mulawenc->channels);
- }
-
- if (GST_BUFFER_SIZE (outbuf) < mulaw_size) {
- /* pad-alloc can suggest a smaller size */
- gst_buffer_unref (outbuf);
- outbuf = gst_buffer_new_and_alloc (mulaw_size);
- }
-
- mulaw_data = (guint8 *) GST_BUFFER_DATA (outbuf);
-
- /* copy discont flag */
- if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
-
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- GST_BUFFER_DURATION (outbuf) = duration;
-
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawenc->srcpad));
-
- mulaw_encode (linear_data, mulaw_data, mulaw_size);
-
- gst_buffer_unref (buffer);
-
- ret = gst_pad_push (mulawenc->srcpad, outbuf);
-
-done:
- gst_object_unref (mulawenc);
-
- return ret;
-
-not_negotiated:
- {
- GST_DEBUG_OBJECT (mulawenc, "no format negotiated");
- ret = GST_FLOW_NOT_NEGOTIATED;
- gst_buffer_unref (buffer);
- goto done;
- }
-alloc_failed:
- {
- GST_DEBUG_OBJECT (mulawenc, "pad alloc failed");
- gst_buffer_unref (buffer);
- goto done;
- }
-}
--- a/gst_plugins_good/gst/law/mulaw-encode.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_MULAWENCODE_H__
-#define __GST_MULAWENCODE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_MULAWENC \
- (gst_mulawenc_get_type())
-#define GST_MULAWENC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MULAWENC,GstMuLawEnc))
-#define GST_MULAWENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MULAWENC,GstMuLawEncClass))
-#define GST_IS_MULAWENC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULAWENC))
-#define GST_IS_MULAWENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULAWENC))
-
-typedef struct _GstMuLawEnc GstMuLawEnc;
-typedef struct _GstMuLawEncClass GstMuLawEncClass;
-
-struct _GstMuLawEnc {
- GstElement element;
-
- GstPad *sinkpad,*srcpad;
-
- gint channels;
- gint rate;
-};
-
-struct _GstMuLawEncClass {
- GstElementClass parent_class;
-};
-
-GType gst_mulawenc_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_STEREO_H__ */
--- a/gst_plugins_good/gst/law/mulaw.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/* GStreamer PCM/A-Law conversions
- *
- * 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.1 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "mulaw-encode.h"
-#include "mulaw-decode.h"
-
-GstStaticPadTemplate mulaw_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "rate = (int) [ 8000, 192000 ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
- );
-
-GstStaticPadTemplate mulaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-mulaw, "
- "rate = [ 8000 , 192000 ], " "channels = [ 1 , 2 ]")
- );
-
-GstStaticPadTemplate mulaw_enc_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "rate = (int) [ 8000, 192000 ], "
- "channels = (int) [ 1, 2 ], "
- "endianness = (int) BYTE_ORDER, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
- );
-
-GstStaticPadTemplate mulaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-mulaw, "
- "rate = [ 8000 , 192000 ], " "channels = [ 1 , 2 ]")
- );
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "mulawenc",
- GST_RANK_NONE, GST_TYPE_MULAWENC) ||
- !gst_element_register (plugin, "mulawdec",
- GST_RANK_PRIMARY, GST_TYPE_MULAWDEC))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "mulaw",
- "MuLaw audio conversion routines",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
-
-
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
--- a/gst_plugins_good/gst/mpegaudioparse/gstmpegaudioparse.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2199 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2006-2007> Jan Schmidt <thaytan@mad.scientist.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "../../config.h"
-#endif
-
-#include <string.h>
-
-#include "gstmpegaudioparse.h"
-
-GST_DEBUG_CATEGORY_STATIC (mp3parse_debug);
-#define GST_CAT_DEFAULT mp3parse_debug
-
-#define MP3_CHANNEL_MODE_UNKNOWN -1
-#define MP3_CHANNEL_MODE_STEREO 0
-#define MP3_CHANNEL_MODE_JOINT_STEREO 1
-#define MP3_CHANNEL_MODE_DUAL_CHANNEL 2
-#define MP3_CHANNEL_MODE_MONO 3
-
-#define CRC_UNKNOWN -1
-#define CRC_PROTECTED 0
-#define CRC_NOT_PROTECTED 1
-
-#define XING_FRAMES_FLAG 0x0001
-#define XING_BYTES_FLAG 0x0002
-#define XING_TOC_FLAG 0x0004
-#define XING_VBR_SCALE_FLAG 0x0008
-
-#ifndef GST_READ_UINT24_BE
-#define GST_READ_UINT24_BE(p) (p[2] | (p[1] << 8) | (p[0] << 16))
-#endif
-
-/* Minimum number of consecutive, valid-looking frames to consider
- for resyncing */
-#define MIN_RESYNC_FRAMES 3
-
-static inline MPEGAudioSeekEntry *
-mpeg_audio_seek_entry_new ()
-{
- return g_slice_new (MPEGAudioSeekEntry);
-}
-
-static inline void
-mpeg_audio_seek_entry_free (MPEGAudioSeekEntry * entry)
-{
- g_slice_free (MPEGAudioSeekEntry, entry);
-}
-
-/* elementfactory information */
-static GstElementDetails mp3parse_details = {
- "MPEG1 Audio Parser",
- "Codec/Parser/Audio",
- "Parses and frames mpeg1 audio streams (levels 1-3), provides seek",
- "Jan Schmidt <thaytan@mad.scientist.com>\n"
- "Erik Walthinsen <omega@cse.ogi.edu>"
-};
-
-static GstStaticPadTemplate mp3_src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/mpeg, "
- "mpegversion = (int) 1, "
- "layer = (int) [ 1, 3 ], "
- "rate = (int) [ 8000, 48000 ], channels = (int) [ 1, 2 ],"
- "parsed=(boolean) true")
- );
-
-static GstStaticPadTemplate mp3_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) 1, parsed=(boolean)false")
- );
-
-/* GstMPEGAudioParse signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- ARG_SKIP,
- ARG_BIT_RATE
- /* FILL ME */
-};
-
-
-static void gst_mp3parse_class_init (GstMPEGAudioParseClass * klass);
-static void gst_mp3parse_base_init (gpointer klass);
-static void gst_mp3parse_init (GstMPEGAudioParse * mp3parse,
- GstMPEGAudioParseClass * klass);
-
-static gboolean gst_mp3parse_sink_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_mp3parse_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean mp3parse_src_query (GstPad * pad, GstQuery * query);
-static const GstQueryType *mp3parse_get_query_types (GstPad * pad);
-static gboolean mp3parse_src_event (GstPad * pad, GstEvent * event);
-
-static int head_check (GstMPEGAudioParse * mp3parse, unsigned long head);
-
-static void gst_mp3parse_dispose (GObject * object);
-static void gst_mp3parse_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_mp3parse_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_mp3parse_change_state (GstElement * element,
- GstStateChange transition);
-static GstFlowReturn
-gst_mp3parse_handle_data (GstMPEGAudioParse * mp3parse, gboolean at_eos);
-
-static gboolean mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse,
- gint64 bytepos, GstClockTime * ts, gboolean from_total_time);
-static gboolean
-mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total);
-static gboolean
-mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total);
-
-GST_BOILERPLATE (GstMPEGAudioParse, gst_mp3parse, GstElement, GST_TYPE_ELEMENT);
-
-#define GST_TYPE_MP3_CHANNEL_MODE (gst_mp3_channel_mode_get_type())
-
-static const GEnumValue mp3_channel_mode[] = {
- {MP3_CHANNEL_MODE_UNKNOWN, "Unknown", "unknown"},
- {MP3_CHANNEL_MODE_MONO, "Mono", "mono"},
- {MP3_CHANNEL_MODE_DUAL_CHANNEL, "Dual Channel", "dual-channel"},
- {MP3_CHANNEL_MODE_JOINT_STEREO, "Joint Stereo", "joint-stereo"},
- {MP3_CHANNEL_MODE_STEREO, "Stereo", "stereo"},
- {0, NULL, NULL},
-};
-
-static GType
-gst_mp3_channel_mode_get_type (void)
-{
- static GType mp3_channel_mode_type = 0;
-
- if (!mp3_channel_mode_type) {
- mp3_channel_mode_type =
- g_enum_register_static ("GstMp3ChannelMode", mp3_channel_mode);
- }
- return mp3_channel_mode_type;
-}
-
-static const gchar *
-gst_mp3_channel_mode_get_nick (gint mode)
-{
- guint i;
- for (i = 0; i < G_N_ELEMENTS (mp3_channel_mode); i++) {
- if (mp3_channel_mode[i].value == mode)
- return mp3_channel_mode[i].value_nick;
- }
- return NULL;
-}
-
-static const guint mp3types_bitrates[2][3][16] = {
- {
- {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
- {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
- },
- {
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
- },
-};
-
-static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
-{22050, 24000, 16000},
-{11025, 12000, 8000}
-};
-
-static inline guint
-mp3_type_frame_length_from_header (GstMPEGAudioParse * mp3parse, guint32 header,
- guint * put_version, guint * put_layer, guint * put_channels,
- guint * put_bitrate, guint * put_samplerate, guint * put_mode,
- guint * put_crc)
-{
- guint length;
- gulong mode, samplerate, bitrate, layer, channels, padding, crc;
- gulong version;
- gint lsf, mpg25;
-
- if (header & (1 << 20)) {
- lsf = (header & (1 << 19)) ? 0 : 1;
- mpg25 = 0;
- } else {
- lsf = 1;
- mpg25 = 1;
- }
-
- version = 1 + lsf + mpg25;
-
- layer = 4 - ((header >> 17) & 0x3);
-
- crc = (header >> 16) & 0x1;
-
- bitrate = (header >> 12) & 0xF;
- bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
- /* The caller has ensured we have a valid header, so bitrate can't be
- zero here. */
- g_assert (bitrate != 0);
-
- samplerate = (header >> 10) & 0x3;
- samplerate = mp3types_freqs[lsf + mpg25][samplerate];
-
- padding = (header >> 9) & 0x1;
-
- mode = (header >> 6) & 0x3;
- channels = (mode == 3) ? 1 : 2;
-
- switch (layer) {
- case 1:
- length = 4 * ((bitrate * 12) / samplerate + padding);
- break;
- case 2:
- length = (bitrate * 144) / samplerate + padding;
- break;
- default:
- case 3:
- length = (bitrate * 144) / (samplerate << lsf) + padding;
- break;
- }
-
- GST_DEBUG_OBJECT (mp3parse, "Calculated mp3 frame length of %u bytes",
- length);
- GST_DEBUG_OBJECT (mp3parse, "samplerate = %lu, bitrate = %lu, version = %lu, "
- "layer = %lu, channels = %lu, mode = %s", samplerate, bitrate, version,
- layer, channels, gst_mp3_channel_mode_get_nick (mode));
-
- if (put_version)
- *put_version = version;
- if (put_layer)
- *put_layer = layer;
- if (put_channels)
- *put_channels = channels;
- if (put_bitrate)
- *put_bitrate = bitrate;
- if (put_samplerate)
- *put_samplerate = samplerate;
- if (put_mode)
- *put_mode = mode;
- if (put_crc)
- *put_crc = crc;
-
- return length;
-}
-
-static GstCaps *
-mp3_caps_create (guint version, guint layer, guint channels, guint samplerate)
-{
- GstCaps *new;
-
- g_assert (version);
- g_assert (layer);
- g_assert (samplerate);
- g_assert (channels);
-
- new = gst_caps_new_simple ("audio/mpeg",
- "mpegversion", G_TYPE_INT, 1,
- "mpegaudioversion", G_TYPE_INT, version,
- "layer", G_TYPE_INT, layer,
- "rate", G_TYPE_INT, samplerate,
- "channels", G_TYPE_INT, channels, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
-
- return new;
-}
-
-static void
-gst_mp3parse_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mp3_sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&mp3_src_template));
-
- GST_DEBUG_CATEGORY_INIT (mp3parse_debug, "mp3parse", 0, "MPEG Audio Parser");
-
- gst_element_class_set_details (element_class, &mp3parse_details);
-}
-
-static void
-gst_mp3parse_class_init (GstMPEGAudioParseClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->set_property = gst_mp3parse_set_property;
- gobject_class->get_property = gst_mp3parse_get_property;
- gobject_class->dispose = gst_mp3parse_dispose;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP,
- g_param_spec_int ("skip", "skip", "skip",
- G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BIT_RATE,
- g_param_spec_int ("bitrate", "Bitrate", "Bit Rate",
- G_MININT, G_MAXINT, 0, G_PARAM_READABLE));
-
- gstelement_class->change_state = gst_mp3parse_change_state;
-
-/* register tags */
-#define GST_TAG_CRC "has-crc"
-#define GST_TAG_MODE "channel-mode"
-
- gst_tag_register (GST_TAG_CRC, GST_TAG_FLAG_META, G_TYPE_BOOLEAN,
- "has crc", "Using CRC", NULL);
- gst_tag_register (GST_TAG_MODE, GST_TAG_FLAG_ENCODED, G_TYPE_STRING,
- "channel mode", "MPEG audio channel mode", NULL);
-
- g_type_class_ref (GST_TYPE_MP3_CHANNEL_MODE);
-}
-
-static void
-gst_mp3parse_reset (GstMPEGAudioParse * mp3parse)
-{
- mp3parse->skip = 0;
- mp3parse->resyncing = TRUE;
- mp3parse->next_ts = GST_CLOCK_TIME_NONE;
- mp3parse->cur_offset = -1;
-
- mp3parse->sync_offset = 0;
- mp3parse->tracked_offset = 0;
- mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
- mp3parse->pending_offset = -1;
-
- gst_adapter_clear (mp3parse->adapter);
-
- mp3parse->rate = mp3parse->channels = mp3parse->layer = -1;
- mp3parse->version = 1;
- mp3parse->max_bitreservoir = GST_CLOCK_TIME_NONE;
-
- mp3parse->avg_bitrate = 0;
- mp3parse->bitrate_sum = 0;
- mp3parse->last_posted_bitrate = 0;
- mp3parse->frame_count = 0;
- mp3parse->sent_codec_tag = FALSE;
-
- mp3parse->last_posted_crc = CRC_UNKNOWN;
- mp3parse->last_posted_channel_mode = MP3_CHANNEL_MODE_UNKNOWN;
-
- mp3parse->xing_flags = 0;
- mp3parse->xing_bitrate = 0;
- mp3parse->xing_frames = 0;
- mp3parse->xing_total_time = 0;
- mp3parse->xing_bytes = 0;
- mp3parse->xing_vbr_scale = 0;
- memset (mp3parse->xing_seek_table, 0, 100);
- memset (mp3parse->xing_seek_table_inverse, 0, 256);
-
- mp3parse->vbri_bitrate = 0;
- mp3parse->vbri_frames = 0;
- mp3parse->vbri_total_time = 0;
- mp3parse->vbri_bytes = 0;
- mp3parse->vbri_seek_points = 0;
- g_free (mp3parse->vbri_seek_table);
- mp3parse->vbri_seek_table = NULL;
-
- if (mp3parse->seek_table) {
- g_list_foreach (mp3parse->seek_table, (GFunc) mpeg_audio_seek_entry_free,
- NULL);
- g_list_free (mp3parse->seek_table);
- mp3parse->seek_table = NULL;
- }
-
- g_mutex_lock (mp3parse->pending_seeks_lock);
- if (mp3parse->pending_accurate_seeks) {
- g_slist_foreach (mp3parse->pending_accurate_seeks, (GFunc) g_free, NULL);
- g_slist_free (mp3parse->pending_accurate_seeks);
- mp3parse->pending_accurate_seeks = NULL;
- }
- if (mp3parse->pending_nonaccurate_seeks) {
- g_slist_foreach (mp3parse->pending_nonaccurate_seeks, (GFunc) g_free, NULL);
- g_slist_free (mp3parse->pending_nonaccurate_seeks);
- mp3parse->pending_nonaccurate_seeks = NULL;
- }
- g_mutex_unlock (mp3parse->pending_seeks_lock);
-
- if (mp3parse->pending_segment) {
- GstEvent **eventp = &mp3parse->pending_segment;
-
- gst_event_replace (eventp, NULL);
- }
-
- mp3parse->exact_position = FALSE;
- gst_segment_init (&mp3parse->segment, GST_FORMAT_TIME);
-}
-
-static void
-gst_mp3parse_init (GstMPEGAudioParse * mp3parse, GstMPEGAudioParseClass * klass)
-{
- mp3parse->sinkpad =
- gst_pad_new_from_static_template (&mp3_sink_template, "sink");
- gst_pad_set_event_function (mp3parse->sinkpad, gst_mp3parse_sink_event);
- gst_pad_set_chain_function (mp3parse->sinkpad, gst_mp3parse_chain);
- gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->sinkpad);
-
- mp3parse->srcpad =
- gst_pad_new_from_static_template (&mp3_src_template, "src");
- gst_pad_use_fixed_caps (mp3parse->srcpad);
- gst_pad_set_event_function (mp3parse->srcpad, mp3parse_src_event);
- gst_pad_set_query_function (mp3parse->srcpad, mp3parse_src_query);
- gst_pad_set_query_type_function (mp3parse->srcpad, mp3parse_get_query_types);
- gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->srcpad);
-
- mp3parse->adapter = gst_adapter_new ();
- mp3parse->pending_seeks_lock = g_mutex_new ();
-
- gst_mp3parse_reset (mp3parse);
-}
-
-static void
-gst_mp3parse_dispose (GObject * object)
-{
- GstMPEGAudioParse *mp3parse = GST_MP3PARSE (object);
-
- gst_mp3parse_reset (mp3parse);
-
- if (mp3parse->adapter) {
- g_object_unref (mp3parse->adapter);
- mp3parse->adapter = NULL;
- }
- g_mutex_free (mp3parse->pending_seeks_lock);
- mp3parse->pending_seeks_lock = NULL;
-
- g_list_foreach (mp3parse->pending_events, (GFunc) gst_mini_object_unref,
- NULL);
- g_list_free (mp3parse->pending_events);
- mp3parse->pending_events = NULL;
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static gboolean
-gst_mp3parse_sink_event (GstPad * pad, GstEvent * event)
-{
- gboolean res = TRUE;
- GstMPEGAudioParse *mp3parse;
- GstEvent **eventp;
-
- mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- {
- gdouble rate, applied_rate;
- GstFormat format;
- gint64 start, stop, pos;
- gboolean update;
- MPEGAudioPendingAccurateSeek *seek = NULL;
- GSList *node;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
- &format, &start, &stop, &pos);
-
- g_mutex_lock (mp3parse->pending_seeks_lock);
- if (format == GST_FORMAT_BYTES && mp3parse->pending_accurate_seeks) {
-
- for (node = mp3parse->pending_accurate_seeks; node; node = node->next) {
- MPEGAudioPendingAccurateSeek *tmp = node->data;
-
- if (tmp->upstream_start == pos) {
- seek = tmp;
- break;
- }
- }
- if (seek) {
- GstSegment *s = &seek->segment;
-
- event =
- gst_event_new_new_segment_full (FALSE, s->rate, s->applied_rate,
- GST_FORMAT_TIME, s->start, s->stop, s->last_stop);
-
- mp3parse->segment = seek->segment;
-
- mp3parse->resyncing = FALSE;
- mp3parse->cur_offset = pos;
- mp3parse->next_ts = seek->timestamp_start;
- mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
- mp3parse->tracked_offset = 0;
- mp3parse->sync_offset = 0;
-
- gst_event_parse_new_segment_full (event, &update, &rate,
- &applied_rate, &format, &start, &stop, &pos);
-
- GST_DEBUG_OBJECT (mp3parse,
- "Pushing accurate newseg rate %g, applied rate %g, "
- "format %d, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT
- ", pos %" G_GINT64_FORMAT, rate, applied_rate, format, start,
- stop, pos);
-
- g_free (seek);
- mp3parse->pending_accurate_seeks =
- g_slist_delete_link (mp3parse->pending_accurate_seeks, node);
-
- g_mutex_unlock (mp3parse->pending_seeks_lock);
- res = gst_pad_push_event (mp3parse->srcpad, event);
-
- return res;
- } else {
- GST_WARNING_OBJECT (mp3parse,
- "Accurate seek not possible, didn't get an appropiate upstream segment");
- }
- }
- g_mutex_unlock (mp3parse->pending_seeks_lock);
-
- mp3parse->exact_position = FALSE;
-
- if (format == GST_FORMAT_BYTES) {
- GstClockTime seg_start, seg_stop, seg_pos;
-
- /* stop time is allowed to be open-ended, but not start & pos */
- if (!mp3parse_bytepos_to_time (mp3parse, stop, &seg_stop, FALSE))
- seg_stop = GST_CLOCK_TIME_NONE;
- if (mp3parse_bytepos_to_time (mp3parse, start, &seg_start, FALSE) &&
- mp3parse_bytepos_to_time (mp3parse, pos, &seg_pos, FALSE)) {
- gst_event_unref (event);
-
- /* search the pending nonaccurate seeks */
- g_mutex_lock (mp3parse->pending_seeks_lock);
- seek = NULL;
- for (node = mp3parse->pending_nonaccurate_seeks; node;
- node = node->next) {
- MPEGAudioPendingAccurateSeek *tmp = node->data;
-
- if (tmp->upstream_start == pos) {
- seek = tmp;
- break;
- }
- }
-
- if (seek) {
- if (seek->segment.stop == -1) {
- /* corrent the segment end, because non-accurate seeks might make
- * our streaming end earlier (see bug #603695) */
- seg_stop = -1;
- }
- g_free (seek);
- mp3parse->pending_nonaccurate_seeks =
- g_slist_delete_link (mp3parse->pending_nonaccurate_seeks, node);
- }
- g_mutex_unlock (mp3parse->pending_seeks_lock);
-
- event = gst_event_new_new_segment_full (update, rate, applied_rate,
- GST_FORMAT_TIME, seg_start, seg_stop, seg_pos);
- format = GST_FORMAT_TIME;
- GST_DEBUG_OBJECT (mp3parse, "Converted incoming segment to TIME. "
- "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
- ", pos = %" GST_TIME_FORMAT, GST_TIME_ARGS (seg_start),
- GST_TIME_ARGS (seg_stop), GST_TIME_ARGS (seg_pos));
- }
- }
-
- if (format != GST_FORMAT_TIME) {
- /* Unknown incoming segment format. Output a default open-ended
- * TIME segment */
- gst_event_unref (event);
- event = gst_event_new_new_segment_full (update, rate, applied_rate,
- GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
- }
-
- mp3parse->resyncing = TRUE;
- mp3parse->cur_offset = -1;
- mp3parse->next_ts = GST_CLOCK_TIME_NONE;
- mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
- mp3parse->tracked_offset = 0;
- mp3parse->sync_offset = 0;
- /* also clear leftover data if clearing so much state */
- gst_adapter_clear (mp3parse->adapter);
-
- gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
- &format, &start, &stop, &pos);
- GST_DEBUG_OBJECT (mp3parse, "Pushing newseg rate %g, applied rate %g, "
- "format %d, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT
- ", pos %" G_GINT64_FORMAT, rate, applied_rate, format, start, stop,
- pos);
-
- gst_segment_set_newsegment_full (&mp3parse->segment, update, rate,
- applied_rate, format, start, stop, pos);
-
- /* save the segment for later, right before we push a new buffer so that
- * the caps are fixed and the next linked element can receive the segment. */
- eventp = &mp3parse->pending_segment;
- gst_event_replace (eventp, event);
- gst_event_unref (event);
- res = TRUE;
- break;
- }
- case GST_EVENT_FLUSH_STOP:
- /* Clear our adapter and set up for a new position */
- gst_adapter_clear (mp3parse->adapter);
- eventp = &mp3parse->pending_segment;
- gst_event_replace (eventp, NULL);
- res = gst_pad_push_event (mp3parse->srcpad, event);
- break;
- case GST_EVENT_EOS:
- /* If we haven't processed any frames yet, then make sure we process
- at least whatever's in our adapter */
- if (mp3parse->frame_count == 0) {
- gst_mp3parse_handle_data (mp3parse, TRUE);
-
- /* If we STILL have zero frames processed, fire an error */
- if (mp3parse->frame_count == 0) {
- GST_ELEMENT_ERROR (mp3parse, STREAM, WRONG_TYPE,
- ("No valid frames found before end of stream"), (NULL));
- }
- }
- /* fall through */
- default:
- if (mp3parse->pending_segment &&
- (GST_EVENT_TYPE (event) != GST_EVENT_EOS) &&
- (GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START)) {
- /* Cache all events except EOS and the ones above if we have
- * a pending segment */
- mp3parse->pending_events =
- g_list_append (mp3parse->pending_events, event);
- } else {
- res = gst_pad_push_event (mp3parse->srcpad, event);
- }
- break;
- }
-
- gst_object_unref (mp3parse);
-
- return res;
-}
-
-static void
-gst_mp3parse_add_index_entry (GstMPEGAudioParse * mp3parse, guint64 offset,
- GstClockTime ts)
-{
- MPEGAudioSeekEntry *entry, *last;
-
- if (G_LIKELY (mp3parse->seek_table != NULL)) {
- last = mp3parse->seek_table->data;
-
- if (last->byte >= offset)
- return;
-
- if (GST_CLOCK_DIFF (last->timestamp, ts) < mp3parse->idx_interval)
- return;
- }
-
- entry = mpeg_audio_seek_entry_new ();
- entry->byte = offset;
- entry->timestamp = ts;
- mp3parse->seek_table = g_list_prepend (mp3parse->seek_table, entry);
-
- GST_LOG_OBJECT (mp3parse, "Adding index entry %" GST_TIME_FORMAT " @ offset "
- "0x%08" G_GINT64_MODIFIER "x", GST_TIME_ARGS (ts), offset);
-}
-
-/* Prepare a buffer of the indicated size, timestamp it and output */
-static GstFlowReturn
-gst_mp3parse_emit_frame (GstMPEGAudioParse * mp3parse, guint size,
- guint mode, guint crc)
-{
- GstBuffer *outbuf;
- guint bitrate;
- GstFlowReturn ret = GST_FLOW_OK;
- GstClockTime push_start;
- GstTagList *taglist;
-
- outbuf = gst_adapter_take_buffer (mp3parse->adapter, size);
-
- GST_BUFFER_DURATION (outbuf) =
- gst_util_uint64_scale (GST_SECOND, mp3parse->spf, mp3parse->rate);
-
- GST_BUFFER_OFFSET (outbuf) = mp3parse->cur_offset;
-
- /* Check if we have a pending timestamp from an incoming buffer to apply
- * here */
- if (GST_CLOCK_TIME_IS_VALID (mp3parse->pending_ts)) {
- if (mp3parse->tracked_offset >= mp3parse->pending_offset) {
- /* If the incoming timestamp differs from our expected by more than
- * half a frame, then take it instead of our calculated timestamp.
- * This avoids creating imperfect streams just because of
- * quantization in the container timestamping */
- GstClockTimeDiff diff = mp3parse->next_ts - mp3parse->pending_ts;
- GstClockTimeDiff thresh = GST_BUFFER_DURATION (outbuf) / 2;
-
- if (diff < -thresh || diff > thresh) {
- GST_DEBUG_OBJECT (mp3parse, "Updating next_ts from %" GST_TIME_FORMAT
- " to pending ts %" GST_TIME_FORMAT
- " at offset %" G_GINT64_FORMAT " (pending offset was %"
- G_GINT64_FORMAT ")", GST_TIME_ARGS (mp3parse->next_ts),
- GST_TIME_ARGS (mp3parse->pending_ts), mp3parse->tracked_offset,
- mp3parse->pending_offset);
- mp3parse->next_ts = mp3parse->pending_ts;
- }
- mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
- }
- }
-
- /* Decide what timestamp we're going to apply */
- if (GST_CLOCK_TIME_IS_VALID (mp3parse->next_ts)) {
- GST_BUFFER_TIMESTAMP (outbuf) = mp3parse->next_ts;
- } else {
- GstClockTime ts;
-
- /* No timestamp yet, convert our offset to a timestamp if we can, or
- * start at 0 */
- if (mp3parse_bytepos_to_time (mp3parse, mp3parse->cur_offset, &ts, FALSE) &&
- GST_CLOCK_TIME_IS_VALID (ts))
- GST_BUFFER_TIMESTAMP (outbuf) = ts;
- else {
- GST_BUFFER_TIMESTAMP (outbuf) = 0;
- }
- }
-
- if (GST_BUFFER_TIMESTAMP (outbuf) == 0)
- mp3parse->exact_position = TRUE;
-
- if (mp3parse->seekable &&
- mp3parse->exact_position && GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
- mp3parse->cur_offset != GST_BUFFER_OFFSET_NONE) {
- gst_mp3parse_add_index_entry (mp3parse, mp3parse->cur_offset,
- GST_BUFFER_TIMESTAMP (outbuf));
- }
-
- /* Update our byte offset tracking */
- if (mp3parse->cur_offset != -1) {
- mp3parse->cur_offset += size;
- }
- mp3parse->tracked_offset += size;
-
- if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf))
- mp3parse->next_ts =
- GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf);
-
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mp3parse->srcpad));
-
- /* Post a bitrate tag if we need to before pushing the buffer */
- if (mp3parse->xing_bitrate != 0)
- bitrate = mp3parse->xing_bitrate;
- else if (mp3parse->vbri_bitrate != 0)
- bitrate = mp3parse->vbri_bitrate;
- else
- bitrate = mp3parse->avg_bitrate;
-
- /* we will create a taglist (if any of the parameters has changed)
- * to add the tags that changed */
- taglist = NULL;
- if ((mp3parse->last_posted_bitrate / 10000) != (bitrate / 10000)) {
- taglist = gst_tag_list_new ();
- mp3parse->last_posted_bitrate = bitrate;
- gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE,
- mp3parse->last_posted_bitrate, NULL);
-
- /* Post a new duration message if the average bitrate changes that much
- * so applications can update their cached values
- */
- if ((mp3parse->xing_flags & XING_TOC_FLAG) == 0
- && mp3parse->vbri_total_time == 0) {
- gst_element_post_message (GST_ELEMENT (mp3parse),
- gst_message_new_duration (GST_OBJECT (mp3parse), GST_FORMAT_TIME,
- -1));
- }
- }
-
- if (mp3parse->last_posted_crc != crc) {
- gboolean using_crc;
-
- if (!taglist) {
- taglist = gst_tag_list_new ();
- }
- mp3parse->last_posted_crc = crc;
- if (mp3parse->last_posted_crc == CRC_PROTECTED) {
- using_crc = TRUE;
- } else {
- using_crc = FALSE;
- }
- gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_CRC,
- using_crc, NULL);
- }
-
- if (mp3parse->last_posted_channel_mode != mode) {
- if (!taglist) {
- taglist = gst_tag_list_new ();
- }
- mp3parse->last_posted_channel_mode = mode;
-
- gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_MODE,
- gst_mp3_channel_mode_get_nick (mode), NULL);
- }
-
- /* if the taglist exists, we need to send it */
- if (taglist) {
- gst_element_found_tags_for_pad (GST_ELEMENT (mp3parse),
- mp3parse->srcpad, taglist);
- }
-
- /* We start pushing 9 frames earlier (29 frames for MPEG2) than
- * segment start to be able to decode the first frame we want.
- * 9 (29) frames are the theoretical maximum of frames that contain
- * data for the current frame (bit reservoir).
- */
- if (mp3parse->segment.start == 0) {
- push_start = 0;
- } else if (GST_CLOCK_TIME_IS_VALID (mp3parse->max_bitreservoir)) {
- if (GST_CLOCK_TIME_IS_VALID (mp3parse->segment.start) &&
- mp3parse->segment.start > mp3parse->max_bitreservoir)
- push_start = mp3parse->segment.start - mp3parse->max_bitreservoir;
- else
- push_start = 0;
- } else {
- push_start = mp3parse->segment.start;
- }
-
- if (G_UNLIKELY ((GST_CLOCK_TIME_IS_VALID (push_start) &&
- GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
- GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf)
- < push_start))) {
- GST_DEBUG_OBJECT (mp3parse,
- "Buffer before configured segment range %" GST_TIME_FORMAT
- " to %" GST_TIME_FORMAT ", dropping, timestamp %"
- GST_TIME_FORMAT " duration %" GST_TIME_FORMAT
- ", offset 0x%08" G_GINT64_MODIFIER "x", GST_TIME_ARGS (push_start),
- GST_TIME_ARGS (mp3parse->segment.stop),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
- GST_BUFFER_OFFSET (outbuf));
-
- gst_buffer_unref (outbuf);
- ret = GST_FLOW_OK;
- } else if (G_UNLIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
- GST_CLOCK_TIME_IS_VALID (mp3parse->segment.stop) &&
- GST_BUFFER_TIMESTAMP (outbuf) >=
- mp3parse->segment.stop + GST_BUFFER_DURATION (outbuf))) {
- /* Some mp3 streams have an offset in the timestamps, for which we have to
- * push the frame *after* the end position in order for the decoder to be
- * able to decode everything up until the segment.stop position.
- * That is the reason of the calculated offset */
- GST_DEBUG_OBJECT (mp3parse,
- "Buffer after configured segment range %" GST_TIME_FORMAT " to %"
- GST_TIME_FORMAT ", returning GST_FLOW_UNEXPECTED, timestamp %"
- GST_TIME_FORMAT " duration %" GST_TIME_FORMAT ", offset 0x%08"
- G_GINT64_MODIFIER "x", GST_TIME_ARGS (push_start),
- GST_TIME_ARGS (mp3parse->segment.stop),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
- GST_BUFFER_OFFSET (outbuf));
-
- gst_buffer_unref (outbuf);
- ret = GST_FLOW_UNEXPECTED;
- } else {
- GST_DEBUG_OBJECT (mp3parse,
- "pushing buffer of %d bytes, timestamp %" GST_TIME_FORMAT
- ", offset 0x%08" G_GINT64_MODIFIER "x", size,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_BUFFER_OFFSET (outbuf));
- mp3parse->segment.last_stop = GST_BUFFER_TIMESTAMP (outbuf);
- /* push any pending segment now */
- if (mp3parse->pending_segment) {
- gst_pad_push_event (mp3parse->srcpad, mp3parse->pending_segment);
- mp3parse->pending_segment = NULL;
- }
- if (mp3parse->pending_events) {
- GList *l;
-
- for (l = mp3parse->pending_events; l != NULL; l = l->next) {
- gst_pad_push_event (mp3parse->srcpad, GST_EVENT (l->data));
- }
- g_list_free (mp3parse->pending_events);
- mp3parse->pending_events = NULL;
- }
-
- /* set discont if needed */
- if (mp3parse->discont) {
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
- mp3parse->discont = FALSE;
- }
-
- ret = gst_pad_push (mp3parse->srcpad, outbuf);
- }
-
- return ret;
-}
-
-static void
-gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse)
-{
- GstTagList *taglist;
- gchar *codec;
- const guint32 xing_id = 0x58696e67; /* 'Xing' in hex */
- const guint32 info_id = 0x496e666f; /* 'Info' in hex - found in LAME CBR files */
- const guint32 vbri_id = 0x56425249; /* 'VBRI' in hex */
-
- gint offset;
-
- guint64 avail;
- gint64 upstream_total_bytes = 0;
- guint32 read_id;
- const guint8 *data;
-
- /* Output codec tag */
- if (!mp3parse->sent_codec_tag) {
- if (mp3parse->layer == 3) {
- codec = g_strdup_printf ("MPEG %d Audio, Layer %d (MP3)",
- mp3parse->version, mp3parse->layer);
- } else {
- codec = g_strdup_printf ("MPEG %d Audio, Layer %d",
- mp3parse->version, mp3parse->layer);
- }
-
- taglist = gst_tag_list_new ();
- gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
- GST_TAG_AUDIO_CODEC, codec, NULL);
- gst_element_found_tags_for_pad (GST_ELEMENT (mp3parse),
- mp3parse->srcpad, taglist);
- g_free (codec);
-
- mp3parse->sent_codec_tag = TRUE;
- }
- /* end setting the tag */
-
- /* Check first frame for Xing info */
- if (mp3parse->version == 1) { /* MPEG-1 file */
- if (mp3parse->channels == 1)
- offset = 0x11;
- else
- offset = 0x20;
- } else { /* MPEG-2 header */
- if (mp3parse->channels == 1)
- offset = 0x09;
- else
- offset = 0x11;
- }
- /* Skip the 4 bytes of the MP3 header too */
- offset += 4;
-
- /* Check if we have enough data to read the Xing header */
- avail = gst_adapter_available (mp3parse->adapter);
-
- if (avail < offset + 8)
- return;
-
- data = gst_adapter_peek (mp3parse->adapter, offset + 8);
- if (data == NULL)
- return;
- /* The header starts at the provided offset */
- data += offset;
-
- /* obtain real upstream total bytes */
- mp3parse_total_bytes (mp3parse, &upstream_total_bytes);
-
- read_id = GST_READ_UINT32_BE (data);
- if (read_id == xing_id || read_id == info_id) {
- guint32 xing_flags;
- guint bytes_needed = offset + 8;
- gint64 total_bytes;
- GstClockTime total_time;
-
- GST_DEBUG_OBJECT (mp3parse, "Found Xing header marker 0x%x", xing_id);
-
- /* Read 4 base bytes of flags, big-endian */
- xing_flags = GST_READ_UINT32_BE (data + 4);
- if (xing_flags & XING_FRAMES_FLAG)
- bytes_needed += 4;
- if (xing_flags & XING_BYTES_FLAG)
- bytes_needed += 4;
- if (xing_flags & XING_TOC_FLAG)
- bytes_needed += 100;
- if (xing_flags & XING_VBR_SCALE_FLAG)
- bytes_needed += 4;
- if (avail < bytes_needed) {
- GST_DEBUG_OBJECT (mp3parse,
- "Not enough data to read Xing header (need %d)", bytes_needed);
- return;
- }
-
- GST_DEBUG_OBJECT (mp3parse, "Reading Xing header");
- mp3parse->xing_flags = xing_flags;
- data = gst_adapter_peek (mp3parse->adapter, bytes_needed);
- data += offset + 8;
-
- if (xing_flags & XING_FRAMES_FLAG) {
- mp3parse->xing_frames = GST_READ_UINT32_BE (data);
- if (mp3parse->xing_frames == 0) {
- GST_WARNING_OBJECT (mp3parse,
- "Invalid number of frames in Xing header");
- mp3parse->xing_flags &= ~XING_FRAMES_FLAG;
- } else {
- mp3parse->xing_total_time = gst_util_uint64_scale (GST_SECOND,
- (guint64) (mp3parse->xing_frames) * (mp3parse->spf),
- mp3parse->rate);
- }
-
- data += 4;
- } else {
- mp3parse->xing_frames = 0;
- mp3parse->xing_total_time = 0;
- }
-
- if (xing_flags & XING_BYTES_FLAG) {
- mp3parse->xing_bytes = GST_READ_UINT32_BE (data);
- if (mp3parse->xing_bytes == 0) {
- GST_WARNING_OBJECT (mp3parse, "Invalid number of bytes in Xing header");
- mp3parse->xing_flags &= ~XING_BYTES_FLAG;
- }
-
- data += 4;
- } else {
- mp3parse->xing_bytes = 0;
- }
-
- /* If we know the upstream size and duration, compute the
- * total bitrate, rounded up to the nearest kbit/sec */
- if ((total_time = mp3parse->xing_total_time) &&
- (total_bytes = mp3parse->xing_bytes)) {
- mp3parse->xing_bitrate = gst_util_uint64_scale (total_bytes,
- 8 * GST_SECOND, total_time);
- mp3parse->xing_bitrate += 500;
- mp3parse->xing_bitrate -= mp3parse->xing_bitrate % 1000;
- }
-
- if (xing_flags & XING_TOC_FLAG) {
- int i, percent = 0;
- guchar *table = mp3parse->xing_seek_table;
- guchar old = 0, new;
- guint first;
-
- first = data[0];
- GST_DEBUG_OBJECT (mp3parse,
- "Subtracting initial offset of %d bytes from Xing TOC", first);
-
- /* xing seek table: percent time -> 1/256 bytepos */
- for (i = 0; i < 100; i++) {
- new = data[i] - first;
- if (old > new) {
- GST_WARNING_OBJECT (mp3parse, "Skipping broken Xing TOC");
- mp3parse->xing_flags &= ~XING_TOC_FLAG;
- goto skip_toc;
- }
- mp3parse->xing_seek_table[i] = old = new;
- }
-
- /* build inverse table: 1/256 bytepos -> 1/100 percent time */
- for (i = 0; i < 256; i++) {
- while (percent < 99 && table[percent + 1] <= i)
- percent++;
-
- if (table[percent] == i) {
- mp3parse->xing_seek_table_inverse[i] = percent * 100;
- } else if (table[percent] < i && percent < 99) {
- gdouble fa, fb, fx;
- gint a = percent, b = percent + 1;
-
- fa = table[a];
- fb = table[b];
- fx = (b - a) / (fb - fa) * (i - fa) + a;
- mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100);
- } else if (percent == 99) {
- gdouble fa, fb, fx;
- gint a = percent, b = 100;
-
- fa = table[a];
- fb = 256.0;
- fx = (b - a) / (fb - fa) * (i - fa) + a;
- mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100);
- }
- }
- skip_toc:
- data += 100;
- } else {
- memset (mp3parse->xing_seek_table, 0, 100);
- memset (mp3parse->xing_seek_table_inverse, 0, 256);
- }
-
- if (xing_flags & XING_VBR_SCALE_FLAG) {
- mp3parse->xing_vbr_scale = GST_READ_UINT32_BE (data);
- } else
- mp3parse->xing_vbr_scale = 0;
-
- GST_DEBUG_OBJECT (mp3parse, "Xing header reported %u frames, time %"
- GST_TIME_FORMAT ", %u bytes, vbr scale %u", mp3parse->xing_frames,
- GST_TIME_ARGS (mp3parse->xing_total_time), mp3parse->xing_bytes,
- mp3parse->xing_vbr_scale);
-
- /* check for truncated file */
- if (upstream_total_bytes && mp3parse->xing_bytes &&
- mp3parse->xing_bytes * 0.8 > upstream_total_bytes) {
- GST_WARNING_OBJECT (mp3parse, "File appears to have been truncated; "
- "invalidating Xing header duration and size");
- mp3parse->xing_flags &= ~XING_BYTES_FLAG;
- mp3parse->xing_flags &= ~XING_FRAMES_FLAG;
- }
- } else if (read_id == vbri_id) {
- gint64 total_bytes, total_frames;
- GstClockTime total_time;
- guint16 nseek_points;
-
- GST_DEBUG_OBJECT (mp3parse, "Found VBRI header marker 0x%x", vbri_id);
- if (avail < offset + 26) {
- GST_DEBUG_OBJECT (mp3parse,
- "Not enough data to read VBRI header (need %d)", offset + 26);
- return;
- }
-
- GST_DEBUG_OBJECT (mp3parse, "Reading VBRI header");
- data = gst_adapter_peek (mp3parse->adapter, offset + 26);
- data += offset + 4;
-
- if (GST_READ_UINT16_BE (data) != 0x0001) {
- GST_WARNING_OBJECT (mp3parse,
- "Unsupported VBRI version 0x%x", GST_READ_UINT16_BE (data));
- return;
- }
- data += 2;
-
- /* Skip encoder delay */
- data += 2;
-
- /* Skip quality */
- data += 2;
-
- total_bytes = GST_READ_UINT32_BE (data);
- if (total_bytes != 0)
- mp3parse->vbri_bytes = total_bytes;
- data += 4;
-
- total_frames = GST_READ_UINT32_BE (data);
- if (total_frames != 0) {
- mp3parse->vbri_frames = total_frames;
- mp3parse->vbri_total_time = gst_util_uint64_scale (GST_SECOND,
- (guint64) (mp3parse->vbri_frames) * (mp3parse->spf), mp3parse->rate);
- }
- data += 4;
-
- /* If we know the upstream size and duration, compute the
- * total bitrate, rounded up to the nearest kbit/sec */
- if ((total_time = mp3parse->vbri_total_time) &&
- (total_bytes = mp3parse->vbri_bytes)) {
- mp3parse->vbri_bitrate = gst_util_uint64_scale (total_bytes,
- 8 * GST_SECOND, total_time);
- mp3parse->vbri_bitrate += 500;
- mp3parse->vbri_bitrate -= mp3parse->vbri_bitrate % 1000;
- }
-
- nseek_points = GST_READ_UINT16_BE (data);
- data += 2;
-
- if (nseek_points > 0) {
- guint scale, seek_bytes, seek_frames;
- gint i;
-
- mp3parse->vbri_seek_points = nseek_points;
-
- scale = GST_READ_UINT16_BE (data);
- data += 2;
-
- seek_bytes = GST_READ_UINT16_BE (data);
- data += 2;
-
- seek_frames = GST_READ_UINT16_BE (data);
-
- if (scale == 0 || seek_bytes == 0 || seek_bytes > 4 || seek_frames == 0) {
- GST_WARNING_OBJECT (mp3parse, "Unsupported VBRI seek table");
- goto out_vbri;
- }
-
- if (avail < offset + 26 + nseek_points * seek_bytes) {
- GST_WARNING_OBJECT (mp3parse,
- "Not enough data to read VBRI seek table (need %d)",
- offset + 26 + nseek_points * seek_bytes);
- goto out_vbri;
- }
-
- if (seek_frames * nseek_points < total_frames - seek_frames ||
- seek_frames * nseek_points > total_frames + seek_frames) {
- GST_WARNING_OBJECT (mp3parse,
- "VBRI seek table doesn't cover the complete file");
- goto out_vbri;
- }
-
- data =
- gst_adapter_peek (mp3parse->adapter,
- offset + 26 + nseek_points * seek_bytes);
- data += offset + 26;
-
-
- /* VBRI seek table: frame/seek_frames -> byte */
- mp3parse->vbri_seek_table = g_new (guint32, nseek_points);
- if (seek_bytes == 4)
- for (i = 0; i < nseek_points; i++) {
- mp3parse->vbri_seek_table[i] = GST_READ_UINT32_BE (data) * scale;
- data += 4;
- } else if (seek_bytes == 3)
- for (i = 0; i < nseek_points; i++) {
- mp3parse->vbri_seek_table[i] = GST_READ_UINT24_BE (data) * scale;
- data += 3;
- } else if (seek_bytes == 2)
- for (i = 0; i < nseek_points; i++) {
- mp3parse->vbri_seek_table[i] = GST_READ_UINT16_BE (data) * scale;
- data += 2;
- } else /* seek_bytes == 1 */
- for (i = 0; i < nseek_points; i++) {
- mp3parse->vbri_seek_table[i] = GST_READ_UINT8 (data) * scale;
- data += 1;
- }
- }
- out_vbri:
-
- GST_DEBUG_OBJECT (mp3parse, "VBRI header reported %u frames, time %"
- GST_TIME_FORMAT ", bytes %u", mp3parse->vbri_frames,
- GST_TIME_ARGS (mp3parse->vbri_total_time), mp3parse->vbri_bytes);
-
- /* check for truncated file */
- if (upstream_total_bytes && mp3parse->vbri_bytes &&
- mp3parse->vbri_bytes * 0.8 > upstream_total_bytes) {
- GST_WARNING_OBJECT (mp3parse, "File appears to have been truncated; "
- "invalidating VBRI header duration and size");
- mp3parse->vbri_valid = FALSE;
- } else {
- mp3parse->vbri_valid = TRUE;
- }
- } else {
- GST_DEBUG_OBJECT (mp3parse,
- "Xing, LAME or VBRI header not found in first frame");
- }
-}
-
-static void
-gst_mp3parse_check_seekability (GstMPEGAudioParse * mp3parse)
-{
- GstQuery *query;
- gboolean seekable = FALSE;
- gint64 start = -1, stop = -1;
- guint idx_interval = 0;
-
- query = gst_query_new_seeking (GST_FORMAT_BYTES);
- if (!gst_pad_peer_query (mp3parse->sinkpad, query)) {
- GST_DEBUG_OBJECT (mp3parse, "seeking query failed");
- goto done;
- }
-
- gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
-
- /* try harder to query upstream size if we didn't get it the first time */
- if (seekable && stop == -1) {
- GstFormat fmt = GST_FORMAT_BYTES;
-
- GST_DEBUG_OBJECT (mp3parse, "doing duration query to fix up unset stop");
- gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, &stop);
- }
-
- /* if upstream doesn't know the size, it's likely that it's not seekable in
- * practice even if it technically may be seekable */
- if (seekable && (start != 0 || stop <= start)) {
- GST_DEBUG_OBJECT (mp3parse, "seekable but unknown start/stop -> disable");
- seekable = FALSE;
- }
-
- /* let's not put every single frame into our index */
- if (seekable) {
- if (stop < 10 * 1024 * 1024)
- idx_interval = 100;
- else if (stop < 100 * 1024 * 1024)
- idx_interval = 500;
- else
- idx_interval = 1000;
- }
-
-done:
-
- GST_INFO_OBJECT (mp3parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
- G_GUINT64_FORMAT ")", seekable, start, stop);
- mp3parse->seekable = seekable;
-
- GST_INFO_OBJECT (mp3parse, "idx_interval: %ums", idx_interval);
- mp3parse->idx_interval = idx_interval * GST_MSECOND;
-
- gst_query_unref (query);
-}
-
-/* Flush some number of bytes and update tracked offsets */
-static void
-gst_mp3parse_flush_bytes (GstMPEGAudioParse * mp3parse, int bytes)
-{
- gst_adapter_flush (mp3parse->adapter, bytes);
- if (mp3parse->cur_offset != -1)
- mp3parse->cur_offset += bytes;
- mp3parse->tracked_offset += bytes;
-}
-
-/* Perform extended validation to check that subsequent headers match
- the first header given here in important characteristics, to avoid
- false sync. We look for a minimum of MIN_RESYNC_FRAMES consecutive
- frames to match their major characteristics.
-
- If at_eos is set to TRUE, we just check that we don't find any invalid
- frames in whatever data is available, rather than requiring a full
- MIN_RESYNC_FRAMES of data.
-
- Returns TRUE if we've seen enough data to validate or reject the frame.
- If TRUE is returned, then *valid contains TRUE if it validated, or false
- if we decided it was false sync.
- */
-static gboolean
-gst_mp3parse_validate_extended (GstMPEGAudioParse * mp3parse, guint32 header,
- int bpf, gboolean at_eos, gboolean * valid)
-{
- guint32 next_header;
- const guint8 *data;
- guint available;
- int frames_found = 1;
- int offset = bpf;
-
- while (frames_found < MIN_RESYNC_FRAMES) {
- /* Check if we have enough data for all these frames, plus the next
- frame header. */
- available = gst_adapter_available (mp3parse->adapter);
- if (available < offset + 4) {
- if (at_eos) {
- /* Running out of data at EOS is fine; just accept it */
- *valid = TRUE;
- return TRUE;
- } else {
- return FALSE;
- }
- }
-
- data = gst_adapter_peek (mp3parse->adapter, offset + 4);
- next_header = GST_READ_UINT32_BE (data + offset);
- GST_DEBUG_OBJECT (mp3parse, "At %d: header=%08X, header2=%08X, bpf=%d",
- offset, (unsigned int) header, (unsigned int) next_header, bpf);
-
-/* mask the bits which are allowed to differ between frames */
-#define HDRMASK ~((0xF << 12) /* bitrate */ | \
- (0x1 << 9) /* padding */ | \
- (0xf << 4) /* mode|mode extension */ | \
- (0xf)) /* copyright|emphasis */
-
- if ((next_header & HDRMASK) != (header & HDRMASK)) {
- /* If any of the unmasked bits don't match, then it's not valid */
- GST_DEBUG_OBJECT (mp3parse, "next header doesn't match "
- "(header=%08X (%08X), header2=%08X (%08X), bpf=%d)",
- (guint) header, (guint) header & HDRMASK, (guint) next_header,
- (guint) next_header & HDRMASK, bpf);
- *valid = FALSE;
- return TRUE;
- } else if ((((next_header >> 12) & 0xf) == 0) ||
- (((next_header >> 12) & 0xf) == 0xf)) {
- /* The essential parts were the same, but the bitrate held an
- invalid value - also reject */
- GST_DEBUG_OBJECT (mp3parse, "next header invalid (bitrate)");
- *valid = FALSE;
- return TRUE;
- }
-
- bpf = mp3_type_frame_length_from_header (mp3parse, next_header,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
- offset += bpf;
- frames_found++;
- }
-
- *valid = TRUE;
- return TRUE;
-}
-
-static GstFlowReturn
-gst_mp3parse_handle_data (GstMPEGAudioParse * mp3parse, gboolean at_eos)
-{
- GstFlowReturn flow = GST_FLOW_OK;
- const guchar *data;
- guint32 header;
- int bpf;
- guint available;
- guint bitrate, layer, rate, channels, version, mode, crc;
- gboolean caps_change;
-
- /* while we still have at least 4 bytes (for the header) available */
- while (gst_adapter_available (mp3parse->adapter) >= 4) {
- /* Get the header bytes, check if they're potentially valid */
- data = gst_adapter_peek (mp3parse->adapter, 4);
- header = GST_READ_UINT32_BE (data);
-
- if (!head_check (mp3parse, header)) {
- /* Not a valid MP3 header; we start looking forward byte-by-byte trying to
- find a place to resync */
- if (!mp3parse->resyncing)
- mp3parse->sync_offset = mp3parse->tracked_offset;
- mp3parse->resyncing = TRUE;
- gst_mp3parse_flush_bytes (mp3parse, 1);
- GST_DEBUG_OBJECT (mp3parse, "wrong header, skipping byte");
- continue;
- }
-
- /* We have a potentially valid header.
- If this is just a normal 'next frame', we go ahead and output it.
-
- However, sometimes, we do additional validation to ensure we haven't
- got false sync (common with mp3 due to the short sync word).
- The additional validation requires that we find several consecutive mp3
- frames with the same major parameters, or reach EOS with a smaller
- number of valid-looking frames.
-
- We do this if:
- - This is the very first frame we've processed
- - We're resyncing after a non-accurate seek, or after losing sync
- due to invalid data.
- - The format of the stream changes in a major way (number of channels,
- sample rate, layer, or mpeg version).
- */
- available = gst_adapter_available (mp3parse->adapter);
-
- if (G_UNLIKELY (mp3parse->resyncing &&
- mp3parse->tracked_offset - mp3parse->sync_offset > 2 * 1024 * 1024))
- goto sync_failure;
-
- bpf = mp3_type_frame_length_from_header (mp3parse, header,
- &version, &layer, &channels, &bitrate, &rate, &mode, &crc);
- g_assert (bpf != 0);
-
- if (channels != mp3parse->channels ||
- rate != mp3parse->rate || layer != mp3parse->layer ||
- version != mp3parse->version)
- caps_change = TRUE;
- else
- caps_change = FALSE;
-
- if (mp3parse->resyncing || caps_change) {
- gboolean valid;
- if (!gst_mp3parse_validate_extended (mp3parse, header, bpf, at_eos,
- &valid)) {
- /* Not enough data to validate; wait for more */
- break;
- }
-
- if (!valid) {
- /* Extended validation failed; we probably got false sync.
- Continue searching from the next byte in the stream */
- if (!mp3parse->resyncing)
- mp3parse->sync_offset = mp3parse->tracked_offset;
- mp3parse->resyncing = TRUE;
- gst_mp3parse_flush_bytes (mp3parse, 1);
- continue;
- }
- }
-
- /* if we don't have the whole frame... */
- if (available < bpf) {
- GST_DEBUG_OBJECT (mp3parse, "insufficient data available, need "
- "%d bytes, have %d", bpf, available);
- break;
- }
-
- if (caps_change) {
- GstCaps *caps;
-
- caps = mp3_caps_create (version, layer, channels, rate);
- gst_pad_set_caps (mp3parse->srcpad, caps);
- gst_caps_unref (caps);
-
- mp3parse->channels = channels;
- mp3parse->rate = rate;
-
- mp3parse->layer = layer;
- mp3parse->version = version;
-
- /* see http://www.codeproject.com/audio/MPEGAudioInfo.asp */
- if (mp3parse->layer == 1)
- mp3parse->spf = 384;
- else if (mp3parse->layer == 2)
- mp3parse->spf = 1152;
- else if (mp3parse->version == 1) {
- mp3parse->spf = 1152;
- } else {
- /* MPEG-2 or "2.5" */
- mp3parse->spf = 576;
- }
-
- mp3parse->max_bitreservoir = gst_util_uint64_scale (GST_SECOND,
- ((version == 1) ? 10 : 30) * mp3parse->spf, mp3parse->rate);
- }
-
- mp3parse->bit_rate = bitrate;
-
- /* Check the first frame for a Xing header to get our total length */
- if (mp3parse->frame_count == 0) {
- /* For the first frame in the file, look for a Xing frame after
- * the header, and output a codec tag */
- gst_mp3parse_handle_first_frame (mp3parse);
-
- /* Check if we're seekable */
- gst_mp3parse_check_seekability (mp3parse);
- }
-
- /* Update VBR stats */
- mp3parse->bitrate_sum += mp3parse->bit_rate;
- mp3parse->frame_count++;
- /* Compute the average bitrate, rounded up to the nearest 1000 bits */
- mp3parse->avg_bitrate =
- (mp3parse->bitrate_sum / mp3parse->frame_count + 500);
- mp3parse->avg_bitrate -= mp3parse->avg_bitrate % 1000;
-
- if (!mp3parse->skip) {
- mp3parse->resyncing = FALSE;
- flow = gst_mp3parse_emit_frame (mp3parse, bpf, mode, crc);
- if (GST_FLOW_IS_FATAL (flow))
- break;
- } else {
- GST_DEBUG_OBJECT (mp3parse, "skipping buffer of %d bytes", bpf);
- gst_mp3parse_flush_bytes (mp3parse, bpf);
- mp3parse->skip--;
- }
- }
-
- return flow;
-
- /* ERRORS */
-sync_failure:
- {
- GST_ELEMENT_ERROR (mp3parse, STREAM, DECODE,
- ("Failed to parse stream"), (NULL));
- return GST_FLOW_ERROR;
- }
-}
-
-static GstFlowReturn
-gst_mp3parse_chain (GstPad * pad, GstBuffer * buf)
-{
- GstMPEGAudioParse *mp3parse;
- GstClockTime timestamp;
-
- mp3parse = GST_MP3PARSE (GST_PAD_PARENT (pad));
-
- GST_LOG_OBJECT (mp3parse, "buffer of %d bytes", GST_BUFFER_SIZE (buf));
-
- timestamp = GST_BUFFER_TIMESTAMP (buf);
-
- mp3parse->discont |= GST_BUFFER_IS_DISCONT (buf);
-
- /* If we don't yet have a next timestamp, save it and the incoming offset
- * so we can apply it to the right outgoing buffer */
- if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
- gint64 avail = gst_adapter_available (mp3parse->adapter);
-
- mp3parse->pending_ts = timestamp;
- mp3parse->pending_offset = mp3parse->tracked_offset + avail;
-
- /* If we have no data pending and the next timestamp is
- * invalid we can use the upstream timestamp for the next frame.
- *
- * This will give us a timestamp if we're resyncing and upstream
- * gave us -1 as offset. */
- if (avail == 0 && !GST_CLOCK_TIME_IS_VALID (mp3parse->next_ts))
- mp3parse->next_ts = timestamp;
-
- GST_LOG_OBJECT (mp3parse, "Have pending ts %" GST_TIME_FORMAT
- " to apply in %" G_GINT64_FORMAT " bytes (@ off %" G_GINT64_FORMAT ")",
- GST_TIME_ARGS (mp3parse->pending_ts), avail, mp3parse->pending_offset);
- }
-
- /* Update the cur_offset we'll apply to outgoing buffers */
- if (mp3parse->cur_offset == -1 && GST_BUFFER_OFFSET (buf) != -1)
- mp3parse->cur_offset = GST_BUFFER_OFFSET (buf);
-
- /* And add the data to the pool */
- gst_adapter_push (mp3parse->adapter, buf);
-
- return gst_mp3parse_handle_data (mp3parse, FALSE);
-}
-
-static gboolean
-head_check (GstMPEGAudioParse * mp3parse, unsigned long head)
-{
- GST_DEBUG_OBJECT (mp3parse, "checking mp3 header 0x%08lx", head);
- /* if it's not a valid sync */
- if ((head & 0xffe00000) != 0xffe00000) {
- GST_WARNING_OBJECT (mp3parse, "invalid sync");
- return FALSE;
- }
- /* if it's an invalid MPEG version */
- if (((head >> 19) & 3) == 0x1) {
- GST_WARNING_OBJECT (mp3parse, "invalid MPEG version: 0x%lx",
- (head >> 19) & 3);
- return FALSE;
- }
- /* if it's an invalid layer */
- if (!((head >> 17) & 3)) {
- GST_WARNING_OBJECT (mp3parse, "invalid layer: 0x%lx", (head >> 17) & 3);
- return FALSE;
- }
- /* if it's an invalid bitrate */
- if (((head >> 12) & 0xf) == 0x0) {
- GST_WARNING_OBJECT (mp3parse, "invalid bitrate: 0x%lx."
- "Free format files are not supported yet", (head >> 12) & 0xf);
- return FALSE;
- }
- if (((head >> 12) & 0xf) == 0xf) {
- GST_WARNING_OBJECT (mp3parse, "invalid bitrate: 0x%lx", (head >> 12) & 0xf);
- return FALSE;
- }
- /* if it's an invalid samplerate */
- if (((head >> 10) & 0x3) == 0x3) {
- GST_WARNING_OBJECT (mp3parse, "invalid samplerate: 0x%lx",
- (head >> 10) & 0x3);
- return FALSE;
- }
-
- if ((head & 0x3) == 0x2) {
- /* Ignore this as there are some files with emphasis 0x2 that can
- * be played fine. See BGO #537235 */
- GST_WARNING_OBJECT (mp3parse, "invalid emphasis: 0x%lx", head & 0x3);
- }
-
- return TRUE;
-}
-
-static void
-gst_mp3parse_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstMPEGAudioParse *src;
-
- src = GST_MP3PARSE (object);
-
- switch (prop_id) {
- case ARG_SKIP:
- src->skip = g_value_get_int (value);
- break;
- default:
- break;
- }
-}
-
-static void
-gst_mp3parse_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstMPEGAudioParse *src;
-
- src = GST_MP3PARSE (object);
-
- switch (prop_id) {
- case ARG_SKIP:
- g_value_set_int (value, src->skip);
- break;
- case ARG_BIT_RATE:
- g_value_set_int (value, src->bit_rate * 1000);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_mp3parse_change_state (GstElement * element, GstStateChange transition)
-{
- GstMPEGAudioParse *mp3parse;
- GstStateChangeReturn result;
-
- mp3parse = GST_MP3PARSE (element);
-
- result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_mp3parse_reset (mp3parse);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static gboolean
-mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total)
-{
- GstFormat fmt = GST_FORMAT_BYTES;
-
- if (gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, total))
- return TRUE;
-
- if (mp3parse->xing_flags & XING_BYTES_FLAG) {
- *total = mp3parse->xing_bytes;
- return TRUE;
- }
-
- if (mp3parse->vbri_bytes != 0 && mp3parse->vbri_valid) {
- *total = mp3parse->vbri_bytes;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total)
-{
- gint64 total_bytes;
-
- *total = GST_CLOCK_TIME_NONE;
-
- if (mp3parse->xing_flags & XING_FRAMES_FLAG) {
- *total = mp3parse->xing_total_time;
- return TRUE;
- }
-
- if (mp3parse->vbri_total_time != 0 && mp3parse->vbri_valid) {
- *total = mp3parse->vbri_total_time;
- return TRUE;
- }
-
- /* Calculate time from the measured bitrate */
- if (!mp3parse_total_bytes (mp3parse, &total_bytes))
- return FALSE;
-
- if (total_bytes != -1
- && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total, TRUE))
- return FALSE;
-
- return TRUE;
-}
-
-/* Convert a timestamp to the file position required to start decoding that
- * timestamp. For now, this just uses the avg bitrate. Later, use an
- * incrementally accumulated seek table */
-static gboolean
-mp3parse_time_to_bytepos (GstMPEGAudioParse * mp3parse, GstClockTime ts,
- gint64 * bytepos)
-{
- gint64 total_bytes;
- GstClockTime total_time;
-
- /* -1 always maps to -1 */
- if (ts == -1) {
- *bytepos = -1;
- return TRUE;
- }
-
- /* If XING seek table exists use this for time->byte conversion */
- if ((mp3parse->xing_flags & XING_TOC_FLAG) &&
- (total_bytes = mp3parse->xing_bytes) &&
- (total_time = mp3parse->xing_total_time)) {
- gdouble fa, fb, fx;
- gdouble percent =
- CLAMP ((100.0 * gst_util_guint64_to_gdouble (ts)) /
- gst_util_guint64_to_gdouble (total_time), 0.0, 100.0);
- gint index = CLAMP (percent, 0, 99);
-
- fa = mp3parse->xing_seek_table[index];
- if (index < 99)
- fb = mp3parse->xing_seek_table[index + 1];
- else
- fb = 256.0;
-
- fx = fa + (fb - fa) * (percent - index);
-
- *bytepos = (1.0 / 256.0) * fx * total_bytes;
-
- return TRUE;
- }
-
- if (mp3parse->vbri_seek_table && (total_bytes = mp3parse->vbri_bytes) &&
- (total_time = mp3parse->vbri_total_time)) {
- gint i, j;
- gdouble a, b, fa, fb;
-
- i = gst_util_uint64_scale (ts, mp3parse->vbri_seek_points - 1, total_time);
- i = CLAMP (i, 0, mp3parse->vbri_seek_points - 1);
-
- a = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time,
- mp3parse->vbri_seek_points));
- fa = 0.0;
- for (j = i; j >= 0; j--)
- fa += mp3parse->vbri_seek_table[j];
-
- if (i + 1 < mp3parse->vbri_seek_points) {
- b = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time,
- mp3parse->vbri_seek_points));
- fb = fa + mp3parse->vbri_seek_table[i + 1];
- } else {
- b = gst_guint64_to_gdouble (total_time);
- fb = total_bytes;
- }
-
- *bytepos = fa + ((fb - fa) / (b - a)) * (gst_guint64_to_gdouble (ts) - a);
-
- return TRUE;
- }
-
- if (mp3parse->avg_bitrate == 0)
- goto no_bitrate;
-
- *bytepos =
- gst_util_uint64_scale (ts, mp3parse->avg_bitrate, (8 * GST_SECOND));
- return TRUE;
-no_bitrate:
- GST_DEBUG_OBJECT (mp3parse, "Cannot seek yet - no average bitrate");
- return FALSE;
-}
-
-static gboolean
-mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse,
- gint64 bytepos, GstClockTime * ts, gboolean from_total_time)
-{
- gint64 total_bytes;
- GstClockTime total_time;
-
- if (bytepos == -1) {
- *ts = GST_CLOCK_TIME_NONE;
- return TRUE;
- }
-
- if (bytepos == 0) {
- *ts = 0;
- return TRUE;
- }
-
- /* If XING seek table exists use this for byte->time conversion */
- if (!from_total_time && (mp3parse->xing_flags & XING_TOC_FLAG) &&
- (total_bytes = mp3parse->xing_bytes) &&
- (total_time = mp3parse->xing_total_time)) {
- gdouble fa, fb, fx;
- gdouble pos;
- gint index;
-
- pos = CLAMP ((bytepos * 256.0) / total_bytes, 0.0, 256.0);
- index = CLAMP (pos, 0, 255);
- fa = mp3parse->xing_seek_table_inverse[index];
- if (index < 255)
- fb = mp3parse->xing_seek_table_inverse[index + 1];
- else
- fb = 10000.0;
-
- fx = fa + (fb - fa) * (pos - index);
-
- *ts = (1.0 / 10000.0) * fx * gst_util_guint64_to_gdouble (total_time);
-
- return TRUE;
- }
-
- if (!from_total_time && mp3parse->vbri_seek_table &&
- (total_bytes = mp3parse->vbri_bytes) &&
- (total_time = mp3parse->vbri_total_time)) {
- gint i = 0;
- guint64 sum = 0;
- gdouble a, b, fa, fb;
-
- do {
- sum += mp3parse->vbri_seek_table[i];
- i++;
- } while (i + 1 < mp3parse->vbri_seek_points
- && sum + mp3parse->vbri_seek_table[i] < bytepos);
- i--;
-
- a = gst_guint64_to_gdouble (sum);
- fa = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time,
- mp3parse->vbri_seek_points));
-
- if (i + 1 < mp3parse->vbri_seek_points) {
- b = a + mp3parse->vbri_seek_table[i + 1];
- fb = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time,
- mp3parse->vbri_seek_points));
- } else {
- b = total_bytes;
- fb = gst_guint64_to_gdouble (total_time);
- }
-
- *ts = gst_gdouble_to_guint64 (fa + ((fb - fa) / (b - a)) * (bytepos - a));
-
- return TRUE;
- }
-
- /* Cannot convert anything except 0 if we don't have a bitrate yet */
- if (mp3parse->avg_bitrate == 0)
- return FALSE;
-
- *ts = (GstClockTime) gst_util_uint64_scale (GST_SECOND, bytepos * 8,
- mp3parse->avg_bitrate);
- return TRUE;
-}
-
-static gboolean
-mp3parse_handle_seek (GstMPEGAudioParse * mp3parse, GstEvent * event)
-{
- GstFormat format;
- gdouble rate;
- GstSeekFlags flags;
- GstSeekType cur_type, stop_type;
- gint64 cur, stop;
- gint64 byte_cur, byte_stop;
- MPEGAudioPendingAccurateSeek *seek;
- GstClockTime start;
-
- gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
- &stop_type, &stop);
-
- GST_DEBUG_OBJECT (mp3parse, "Performing seek to %" GST_TIME_FORMAT,
- GST_TIME_ARGS (cur));
-
- /* For any format other than TIME, see if upstream handles
- * it directly or fail. For TIME, try upstream, but do it ourselves if
- * it fails upstream */
- if (format != GST_FORMAT_TIME) {
- gst_event_ref (event);
- return gst_pad_push_event (mp3parse->sinkpad, event);
- } else {
- gst_event_ref (event);
- if (gst_pad_push_event (mp3parse->sinkpad, event))
- return TRUE;
- }
-
- seek = g_new0 (MPEGAudioPendingAccurateSeek, 1);
-
- seek->segment = mp3parse->segment;
-
- gst_segment_set_seek (&seek->segment, rate, GST_FORMAT_TIME,
- flags, cur_type, cur, stop_type, stop, NULL);
-
- /* Handle TIME based seeks by converting to a BYTE position */
-
- /* For accurate seeking get the frame 9 (MPEG1) or 29 (MPEG2) frames
- * before the one we want to seek to and push them all to the decoder.
- *
- * This is necessary because of the bit reservoir. See
- * http://www.mars.org/mailman/public/mad-dev/2002-May/000634.html
- *
- */
-
- if (flags & GST_SEEK_FLAG_ACCURATE) {
- if (!mp3parse->seek_table) {
- byte_cur = 0;
- byte_stop = -1;
- start = 0;
- } else {
- MPEGAudioSeekEntry *entry = NULL, *start_entry = NULL, *stop_entry = NULL;
- GList *start_node, *stop_node;
- gint64 seek_ts = (cur > mp3parse->max_bitreservoir) ?
- (cur - mp3parse->max_bitreservoir) : 0;
-
- for (start_node = mp3parse->seek_table; start_node;
- start_node = start_node->next) {
- entry = start_node->data;
-
- if (seek_ts >= entry->timestamp) {
- start_entry = entry;
- break;
- }
- }
-
- if (!start_entry) {
- start_entry = mp3parse->seek_table->data;
- start = start_entry->timestamp;
- byte_cur = start_entry->byte;
- } else {
- start = start_entry->timestamp;
- byte_cur = start_entry->byte;
- }
-
- for (stop_node = mp3parse->seek_table; stop_node;
- stop_node = stop_node->next) {
- entry = stop_node->data;
-
- if (stop >= entry->timestamp) {
- stop_node = stop_node->prev;
- stop_entry = (stop_node) ? stop_node->data : NULL;
- break;
- }
- }
-
- if (!stop_entry) {
- byte_stop = -1;
- } else {
- byte_stop = stop_entry->byte;
- }
-
- }
- event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
- byte_cur, stop_type, byte_stop);
- g_mutex_lock (mp3parse->pending_seeks_lock);
- seek->upstream_start = byte_cur;
- seek->timestamp_start = start;
- mp3parse->pending_accurate_seeks =
- g_slist_prepend (mp3parse->pending_accurate_seeks, seek);
- g_mutex_unlock (mp3parse->pending_seeks_lock);
- if (gst_pad_push_event (mp3parse->sinkpad, event)) {
- mp3parse->exact_position = TRUE;
- return TRUE;
- } else {
- mp3parse->exact_position = TRUE;
- g_mutex_lock (mp3parse->pending_seeks_lock);
- mp3parse->pending_accurate_seeks =
- g_slist_remove (mp3parse->pending_accurate_seeks, seek);
- g_mutex_unlock (mp3parse->pending_seeks_lock);
- g_free (seek);
- return FALSE;
- }
- }
-
- mp3parse->exact_position = FALSE;
-
- /* Convert the TIME to the appropriate BYTE position at which to resume
- * decoding. */
- if (!mp3parse_time_to_bytepos (mp3parse, (GstClockTime) cur, &byte_cur))
- goto no_pos;
- if (!mp3parse_time_to_bytepos (mp3parse, (GstClockTime) stop, &byte_stop))
- goto no_pos;
-
- GST_DEBUG_OBJECT (mp3parse, "Seeking to byte range %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, byte_cur, byte_stop);
-
- /* Send BYTE based seek upstream */
- event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
- byte_cur, stop_type, byte_stop);
-
- GST_LOG_OBJECT (mp3parse, "Storing pending seek");
- g_mutex_lock (mp3parse->pending_seeks_lock);
- seek->upstream_start = byte_cur;
- seek->timestamp_start = cur;
- mp3parse->pending_nonaccurate_seeks =
- g_slist_prepend (mp3parse->pending_nonaccurate_seeks, seek);
- g_mutex_unlock (mp3parse->pending_seeks_lock);
- if (gst_pad_push_event (mp3parse->sinkpad, event)) {
- return TRUE;
- } else {
- g_mutex_lock (mp3parse->pending_seeks_lock);
- mp3parse->pending_nonaccurate_seeks =
- g_slist_remove (mp3parse->pending_nonaccurate_seeks, seek);
- g_mutex_unlock (mp3parse->pending_seeks_lock);
- g_free (seek);
- return FALSE;
- }
-
-no_pos:
- GST_DEBUG_OBJECT (mp3parse,
- "Could not determine byte position for desired time");
- return FALSE;
-}
-
-static gboolean
-mp3parse_src_event (GstPad * pad, GstEvent * event)
-{
- GstMPEGAudioParse *mp3parse;
- gboolean res = FALSE;
-
- mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEEK:
- res = mp3parse_handle_seek (mp3parse, event);
- gst_event_unref (event);
- break;
- default:
- res = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (mp3parse);
- return res;
-}
-
-static gboolean
-mp3parse_src_query (GstPad * pad, GstQuery * query)
-{
- GstFormat format;
- GstClockTime total;
- GstMPEGAudioParse *mp3parse;
- gboolean res = FALSE;
- GstPad *peer;
-
- mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
-
- GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:
- gst_query_parse_position (query, &format, NULL);
-
- if (format == GST_FORMAT_BYTES || format == GST_FORMAT_DEFAULT) {
- if (mp3parse->cur_offset != -1) {
- gst_query_set_position (query, GST_FORMAT_BYTES,
- mp3parse->cur_offset);
- res = TRUE;
- }
- } else if (format == GST_FORMAT_TIME) {
- if (mp3parse->next_ts == GST_CLOCK_TIME_NONE)
- goto out;
- gst_query_set_position (query, GST_FORMAT_TIME, mp3parse->next_ts);
- res = TRUE;
- }
-
- /* If no answer above, see if upstream knows */
- if (!res) {
- if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
- res = gst_pad_query (peer, query);
- gst_object_unref (peer);
- if (res)
- goto out;
- }
- }
- break;
- case GST_QUERY_DURATION:
- gst_query_parse_duration (query, &format, NULL);
-
- /* First, see if upstream knows */
- if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
- res = gst_pad_query (peer, query);
- gst_object_unref (peer);
- if (res)
- goto out;
- }
-
- if (format == GST_FORMAT_TIME) {
- if (!mp3parse_total_time (mp3parse, &total) || total == -1)
- goto out;
- gst_query_set_duration (query, format, total);
- res = TRUE;
- }
- break;
- case GST_QUERY_SEEKING:
- gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
-
- /* does upstream handle ? */
- if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
- res = gst_pad_query (peer, query);
- gst_object_unref (peer);
- }
- /* we may be able to help if in TIME */
- if (format == GST_FORMAT_TIME) {
- gboolean seekable;
-
- gst_query_parse_seeking (query, &format, &seekable, NULL, NULL);
- /* already OK if upstream takes care */
- if (!(res && seekable)) {
- gint64 pos;
-
- seekable = TRUE;
- if (!mp3parse_total_time (mp3parse, &total) || total == -1) {
- seekable = FALSE;
- } else if (!mp3parse_time_to_bytepos (mp3parse, 0, &pos)) {
- seekable = FALSE;
- } else {
- GstQuery *q;
-
- q = gst_query_new_seeking (GST_FORMAT_BYTES);
- if (!gst_pad_peer_query (mp3parse->sinkpad, q)) {
- seekable = FALSE;
- } else {
- gst_query_parse_seeking (q, &format, &seekable, NULL, NULL);
- }
- gst_query_unref (q);
- }
- gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, total);
- res = TRUE;
- }
- }
- break;
- default:
- res = gst_pad_query_default (pad, query);
- break;
- }
-
-out:
- gst_object_unref (mp3parse);
- return res;
-}
-
-static const GstQueryType *
-mp3parse_get_query_types (GstPad * pad G_GNUC_UNUSED)
-{
- static const GstQueryType query_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- 0
- };
-
- return query_types;
-}
--- a/gst_plugins_good/gst/mpegaudioparse/gstmpegaudioparse.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __MP3PARSE_H__
-#define __MP3PARSE_H__
-
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_MP3PARSE \
- (gst_mp3parse_get_type())
-#define GST_MP3PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MP3PARSE,GstMPEGAudioParse))
-#define GST_MP3PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MP3PARSE,GstMPEGAudioParseClass))
-#define GST_IS_MP3PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MP3PARSE))
-#define GST_IS_MP3PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MP3PARSE))
-
-typedef struct _GstMPEGAudioParse GstMPEGAudioParse;
-typedef struct _GstMPEGAudioParseClass GstMPEGAudioParseClass;
-typedef struct _MPEGAudioSeekEntry MPEGAudioSeekEntry;
-typedef struct _MPEGAudioPendingAccurateSeek MPEGAudioPendingAccurateSeek;
-
-
-struct _MPEGAudioSeekEntry {
- gint64 byte;
- GstClockTime timestamp;
-};
-
-struct _MPEGAudioPendingAccurateSeek {
- GstSegment segment;
- gint64 upstream_start;
- GstClockTime timestamp_start;
-};
-
-struct _GstMPEGAudioParse {
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
-
- GstSegment segment;
- GstClockTime next_ts;
- gboolean discont;
-
- /* Offset as supplied by incoming buffers */
- gint64 cur_offset;
-
- /* Upcoming timestamp given on an incoming buffer and
- * the offset at which it becomes active */
- GstClockTime pending_ts;
- gint64 pending_offset;
- /* Offset since the last newseg */
- gint64 tracked_offset;
- /* tracked_offset when resyncing started */
- gint64 sync_offset;
-
- GstAdapter *adapter;
-
- guint skip; /* number of frames to skip */
- guint bit_rate; /* in kbps */
- gint channels, rate, layer, version;
- GstClockTime max_bitreservoir;
- gint spf; /* Samples per frame */
-
- gboolean resyncing; /* True when attempting to resync (stricter checks are
- performed) */
- gboolean sent_codec_tag;
-
- /* VBR tracking */
- guint avg_bitrate;
- guint64 bitrate_sum;
- guint frame_count;
- guint last_posted_bitrate;
- gint last_posted_crc;
- guint last_posted_channel_mode;
-
- /* Xing info */
- guint32 xing_flags;
- guint32 xing_frames;
- GstClockTime xing_total_time;
- guint32 xing_bytes;
- /* percent -> filepos mapping */
- guchar xing_seek_table[100];
- /* filepos -> percent mapping */
- guint16 xing_seek_table_inverse[256];
- guint32 xing_vbr_scale;
- guint xing_bitrate;
-
- /* VBRI info */
- guint32 vbri_frames;
- GstClockTime vbri_total_time;
- guint32 vbri_bytes;
- guint vbri_bitrate;
- guint vbri_seek_points;
- guint32 *vbri_seek_table;
- gboolean vbri_valid;
-
- /* Accurate seeking */
- GList *seek_table;
- GMutex *pending_seeks_lock;
- GSList *pending_accurate_seeks;
- gboolean exact_position;
-
- GSList *pending_nonaccurate_seeks;
-
- /* Track whether we're seekable (in BYTES format, if upstream operates in
- * TIME format, we don't care about seekability and assume upstream handles
- * it). The seek table for accurate seeking is not maintained if we're not
- * seekable. */
- gboolean seekable;
-
- /* minimum distance between two index entries */
- GstClockTimeDiff idx_interval;
-
- /* pending segment */
- GstEvent *pending_segment;
- /* pending events */
- GList *pending_events;
-};
-
-struct _GstMPEGAudioParseClass {
- GstElementClass parent_class;
-};
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_mp3parse_get_type(void);
-
-G_END_DECLS
-
-#endif /* __MP3PARSE_H__ */
--- a/gst_plugins_good/gst/mpegaudioparse/gstxingmux.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,681 +0,0 @@
-/*
- * Copyright (c) 2006 Christophe Fergeau <teuf@gnome.org>
- * Copyright (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* Xing SDK: http://www.mp3-tech.org/programmer/sources/vbrheadersdk.zip */
-
-
-/**
- * SECTION:element-xingmux
- *
- * xingmux adds a Xing header to MP3 files. This contains information about the duration and size
- * of the file and a seek table and is very useful for getting an almost correct duration and better
- * seeking on VBR MP3 files.
- *
- * This element will remove any existing Xing, LAME or VBRI headers from the beginning of the file.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch audiotestsrc num-buffers=1000 ! audioconvert ! lame ! xingmux ! filesink location=test.mp3
- * gst-launch filesrc location=test.mp3 ! xingmux ! filesink location=test2.mp3
- * gst-launch filesrc location=test.mp3 ! mp3parse ! xingmux ! filesink location=test2.mp3
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "../../config.h"
-#endif
-
-#include <string.h>
-#include "gstxingmux.h"
-
-GST_DEBUG_CATEGORY_STATIC (xing_mux_debug);
-#define GST_CAT_DEFAULT xing_mux_debug
-
-GST_BOILERPLATE (GstXingMux, gst_xing_mux, GstElement, GST_TYPE_ELEMENT);
-
-/* Xing Header stuff */
-#define GST_XING_FRAME_FIELD (1 << 0)
-#define GST_XING_BYTES_FIELD (1 << 1)
-#define GST_XING_TOC_FIELD (1 << 2)
-#define GST_XING_QUALITY_FIELD (1 << 3)
-
-typedef struct _GstXingSeekEntry
-{
- gint64 timestamp;
- gint byte;
-} GstXingSeekEntry;
-
-static inline GstXingSeekEntry *
-gst_xing_seek_entry_new ()
-{
- return g_slice_new (GstXingSeekEntry);
-}
-
-static inline void
-gst_xing_seek_entry_free (GstXingSeekEntry * entry)
-{
- g_slice_free (GstXingSeekEntry, entry);
-}
-
-static void gst_xing_mux_finalize (GObject * obj);
-static GstStateChangeReturn
-gst_xing_mux_change_state (GstElement * element, GstStateChange transition);
-static GstFlowReturn gst_xing_mux_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_xing_mux_sink_event (GstPad * pad, GstEvent * event);
-
-static GstStaticPadTemplate gst_xing_mux_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/mpeg, "
- "mpegversion = (int) 1, " "layer = (int) [ 1, 3 ]"));
-
-
-static GstStaticPadTemplate gst_xing_mux_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/mpeg, "
- "mpegversion = (int) 1, " "layer = (int) [ 1, 3 ]"));
-static const guint mp3types_bitrates[2][3][16] = {
- {
- {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
- {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
- },
- {
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
- },
-};
-
-static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
-{22050, 24000, 16000},
-{11025, 12000, 8000}
-};
-
-static gboolean
-parse_header (guint32 header, guint * ret_size, guint * ret_spf,
- gulong * ret_rate)
-{
- guint length, spf;
- gulong samplerate, bitrate, layer, padding;
- gint lsf, mpg25;
-
- if ((header & 0xffe00000) != 0xffe00000) {
- g_warning ("invalid sync");
- return FALSE;
- }
-
- if (((header >> 19) & 3) == 0x01) {
- g_warning ("invalid MPEG version");
- return FALSE;
- }
-
- if (((header >> 17) & 3) == 0x00) {
- g_warning ("invalid MPEG layer");
- return FALSE;
- }
-
- if (((header >> 12) & 0xf) == 0xf || ((header >> 12) & 0xf) == 0x0) {
- g_warning ("invalid bitrate");
- return FALSE;
- }
-
- if (((header >> 10) & 0x3) == 0x3) {
- g_warning ("invalid sampling rate");
- return FALSE;
- }
-
- if (header & 0x00000002) {
- g_warning ("invalid emphasis");
- return FALSE;
- }
-
- if (header & (1 << 20)) {
- lsf = (header & (1 << 19)) ? 0 : 1;
- mpg25 = 0;
- } else {
- lsf = 1;
- mpg25 = 1;
- }
-
- layer = 4 - ((header >> 17) & 0x3);
-
- bitrate = (header >> 12) & 0xF;
- bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
- if (bitrate == 0)
- return 0;
-
- samplerate = (header >> 10) & 0x3;
- samplerate = mp3types_freqs[lsf + mpg25][samplerate];
-
- padding = (header >> 9) & 0x1;
-
- switch (layer) {
- case 1:
- length = 4 * ((bitrate * 12) / samplerate + padding);
- break;
- case 2:
- length = (bitrate * 144) / samplerate + padding;
- break;
- default:
- case 3:
- length = (bitrate * 144) / (samplerate << lsf) + padding;
- break;
- }
-
- if (layer == 1)
- spf = 384;
- else if (layer == 2 || lsf == 0)
- spf = 1152;
- else
- spf = 576;
-
- if (ret_size)
- *ret_size = length;
- if (ret_spf)
- *ret_spf = spf;
- if (ret_rate)
- *ret_rate = samplerate;
-
- return TRUE;
-}
-
-static guint
-get_xing_offset (guint32 header)
-{
- guint mpeg_version = (header >> 19) & 0x3;
- guint channel_mode = (header >> 6) & 0x3;
-
- if (mpeg_version == 0x3) {
- if (channel_mode == 0x3) {
- return 0x11;
- } else {
- return 0x20;
- }
- } else {
- if (channel_mode == 0x3) {
- return 0x09;
- } else {
- return 0x11;
- }
- }
-}
-
-static gboolean
-has_xing_header (guint32 header, guchar * data, gsize size)
-{
- data += 4;
- data += get_xing_offset (header);
-
- if (memcmp (data, "Xing", 4) == 0 ||
- memcmp (data, "Info", 4) == 0 || memcmp (data, "VBRI", 4) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static GstBuffer *
-generate_xing_header (GstXingMux * xing)
-{
- guint8 *xing_flags;
- guint32 xing_flags_tmp = 0;
- GstBuffer *xing_header;
- guchar *data;
-
- guint32 header;
- guint32 header_be;
- guint size, spf, xing_offset;
- gulong rate;
- guint bitrate = 0x00;
-
- gint64 duration;
- gint64 byte_count;
-
- header = xing->first_header;
-
- /* Set bitrate and choose lowest possible size */
- do {
- bitrate++;
-
- header &= 0xffff0fff;
- header |= bitrate << 12;
-
- parse_header (header, &size, &spf, &rate);
- xing_offset = get_xing_offset (header);
- } while (size < (4 + xing_offset + 4 + 4 + 4 + 4 + 100) && bitrate < 0xe);
-
- if (bitrate == 0xe) {
- GST_ERROR ("No usable bitrate found!");
- return NULL;
- }
-
- if (gst_pad_alloc_buffer_and_set_caps (xing->srcpad, 0, size,
- GST_PAD_CAPS (xing->srcpad), &xing_header) != GST_FLOW_OK) {
- xing_header = gst_buffer_new_and_alloc (size);
- gst_buffer_set_caps (xing_header, GST_PAD_CAPS (xing->srcpad));
- }
-
- data = GST_BUFFER_DATA (xing_header);
- memset (data, 0, size);
- header_be = GUINT32_TO_BE (header);
- memcpy (data, &header_be, 4);
-
- data += 4;
- data += xing_offset;
-
- memcpy (data, "Xing", 4);
- data += 4;
-
- xing_flags = data;
- data += 4;
-
- if (xing->duration != GST_CLOCK_TIME_NONE) {
- duration = xing->duration;
- } else {
- GstFormat fmt = GST_FORMAT_TIME;
-
- if (!gst_pad_query_peer_duration (xing->sinkpad, &fmt, &duration))
- duration = GST_CLOCK_TIME_NONE;
- }
-
- if (duration != GST_CLOCK_TIME_NONE) {
- guint32 number_of_frames;
-
- /* The Xing Header contains a NumberOfFrames field, which verifies to:
- * Duration = NumberOfFrames *SamplesPerFrame/SamplingRate
- * SamplesPerFrame and SamplingRate are values for the current frame.
- */
- number_of_frames = gst_util_uint64_scale (duration, rate, GST_SECOND) / spf;
- GST_DEBUG ("Setting number of frames to %u", number_of_frames);
- number_of_frames = GUINT32_TO_BE (number_of_frames);
- memcpy (data, &number_of_frames, 4);
- xing_flags_tmp |= GST_XING_FRAME_FIELD;
- data += 4;
- }
-
- if (xing->byte_count != 0) {
- byte_count = xing->byte_count;
- } else {
- GstFormat fmt = GST_FORMAT_BYTES;
-
- if (!gst_pad_query_peer_duration (xing->sinkpad, &fmt, &byte_count))
- byte_count = 0;
- if (byte_count == -1)
- byte_count = 0;
- }
-
- if (byte_count != 0) {
- guint32 nbytes;
-
- if (byte_count > G_MAXUINT32) {
- GST_DEBUG ("Too large stream: %" G_GINT64_FORMAT " > %u bytes",
- byte_count, G_MAXUINT32);
- } else {
- nbytes = byte_count;
- GST_DEBUG ("Setting number of bytes to %u", nbytes);
- nbytes = GUINT32_TO_BE (nbytes);
- memcpy (data, &nbytes, 4);
- xing_flags_tmp |= GST_XING_BYTES_FIELD;
- data += 4;
- }
- }
-
- if (xing->seek_table != NULL && byte_count != 0
- && duration != GST_CLOCK_TIME_NONE) {
- GList *it;
- gint percent = 0;
-
- xing_flags_tmp |= GST_XING_TOC_FIELD;
-
- GST_DEBUG ("Writing seek table");
- for (it = xing->seek_table; it != NULL && percent < 100; it = it->next) {
- GstXingSeekEntry *entry = (GstXingSeekEntry *) it->data;
- gint64 pos;
- guchar byte;
-
- while ((entry->timestamp * 100) / duration >= percent) {
- pos = (entry->byte * 256) / byte_count;
- GST_DEBUG (" %d %% -- %" G_GINT64_FORMAT " 1/256", percent, pos);
- byte = (guchar) pos;
- memcpy (data, &byte, 1);
- data++;
- percent++;
- }
- }
-
- if (percent < 100) {
- guchar b;
- gint i;
-
- memcpy (&b, data - 1, 1);
-
- for (i = percent; i < 100; i++) {
- GST_DEBUG (" %d %% -- %d 1/256", i, b);
- memcpy (data, &b, 1);
- data++;
- }
- }
- }
-
- GST_DEBUG ("Setting Xing flags to 0x%x\n", xing_flags_tmp);
- xing_flags_tmp = GUINT32_TO_BE (xing_flags_tmp);
- memcpy (xing_flags, &xing_flags_tmp, 4);
- return xing_header;
-}
-
-static void
-gst_xing_mux_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- static const GstElementDetails gst_xing_mux_details =
- GST_ELEMENT_DETAILS ("MP3 Xing muxer",
- "Formatter/Metadata",
- "Adds a Xing header to the beginning of a VBR MP3 file",
- "Christophe Fergeau <teuf@gnome.org>");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_xing_mux_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_xing_mux_sink_template));
-
- GST_DEBUG_CATEGORY_INIT (xing_mux_debug, "xingmux", 0, "Xing Header Muxer");
-
- gst_element_class_set_details (element_class, &gst_xing_mux_details);
-}
-
-static void
-gst_xing_mux_class_init (GstXingMuxClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_xing_mux_finalize);
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_xing_mux_change_state);
-}
-
-static void
-gst_xing_mux_finalize (GObject * obj)
-{
- GstXingMux *xing = GST_XING_MUX (obj);
-
- if (xing->adapter) {
- g_object_unref (xing->adapter);
- xing->adapter = NULL;
- }
-
- if (xing->seek_table) {
- g_list_foreach (xing->seek_table, (GFunc) gst_xing_seek_entry_free, NULL);
- g_list_free (xing->seek_table);
- xing->seek_table = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-xing_reset (GstXingMux * xing)
-{
- xing->duration = GST_CLOCK_TIME_NONE;
- xing->byte_count = 0;
-
- gst_adapter_clear (xing->adapter);
-
- if (xing->seek_table) {
- g_list_foreach (xing->seek_table, (GFunc) gst_xing_seek_entry_free, NULL);
- g_list_free (xing->seek_table);
- xing->seek_table = NULL;
- }
-
- xing->sent_xing = FALSE;
-}
-
-
-static void
-gst_xing_mux_init (GstXingMux * xing, GstXingMuxClass * xingmux_class)
-{
- GstElementClass *klass = GST_ELEMENT_CLASS (xingmux_class);
-
- /* pad through which data comes in to the element */
- xing->sinkpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "sink"), "sink");
- gst_pad_set_setcaps_function (xing->sinkpad,
- GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps));
- gst_pad_set_chain_function (xing->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xing_mux_chain));
- gst_pad_set_event_function (xing->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xing_mux_sink_event));
- gst_element_add_pad (GST_ELEMENT (xing), xing->sinkpad);
-
- /* pad through which data goes out of the element */
- xing->srcpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "src"), "src");
- gst_element_add_pad (GST_ELEMENT (xing), xing->srcpad);
-
- xing->adapter = gst_adapter_new ();
-
- xing_reset (xing);
-}
-
-static GstFlowReturn
-gst_xing_mux_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstXingMux *xing = GST_XING_MUX (GST_PAD_PARENT (pad));
- GstFlowReturn ret = GST_FLOW_OK;
-
- gst_adapter_push (xing->adapter, buffer);
-
- while (gst_adapter_available (xing->adapter) >= 4) {
- const guchar *data = gst_adapter_peek (xing->adapter, 4);
- guint32 header;
- GstBuffer *outbuf;
- GstClockTime duration;
- guint size, spf;
- gulong rate;
- GstXingSeekEntry *seek_entry;
-
- header = GST_READ_UINT32_BE (data);
-
- if (!parse_header (header, &size, &spf, &rate)) {
- GST_DEBUG ("Lost sync, resyncing");
- gst_adapter_flush (xing->adapter, 1);
- continue;
- }
-
- if (gst_adapter_available (xing->adapter) < size)
- break;
-
- outbuf = gst_adapter_take_buffer (xing->adapter, size);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (xing->srcpad));
-
- if (!xing->sent_xing) {
- if (has_xing_header (header, GST_BUFFER_DATA (outbuf), size)) {
- GST_LOG_OBJECT (xing, "Dropping old Xing header");
- gst_buffer_unref (outbuf);
- continue;
- } else {
- GstBuffer *xing_header;
- guint64 xing_header_size;
-
- xing->first_header = header;
-
- xing_header = generate_xing_header (xing);
-
- if (xing_header == NULL) {
- GST_ERROR ("Can't generate Xing header");
- gst_buffer_unref (outbuf);
- return GST_FLOW_ERROR;
- }
-
- xing_header_size = GST_BUFFER_SIZE (xing_header);
-
- if (GST_FLOW_IS_FATAL (ret = gst_pad_push (xing->srcpad, xing_header))) {
- GST_ERROR_OBJECT (xing, "Failed to push Xing header: %s",
- gst_flow_get_name (ret));
- gst_buffer_unref (xing_header);
- gst_buffer_unref (outbuf);
- return ret;
- }
-
- xing->byte_count += xing_header_size;
- xing->sent_xing = TRUE;
- }
- }
-
- seek_entry = gst_xing_seek_entry_new ();
- seek_entry->timestamp =
- (xing->duration == GST_CLOCK_TIME_NONE) ? 0 : xing->duration;
- /* Workaround for parsers checking that the first seek table entry is 0 */
- seek_entry->byte = (seek_entry->timestamp == 0) ? 0 : xing->byte_count;
- xing->seek_table = g_list_append (xing->seek_table, seek_entry);
-
- duration = gst_util_uint64_scale (spf, GST_SECOND, rate);
-
- GST_BUFFER_TIMESTAMP (outbuf) =
- (xing->duration == GST_CLOCK_TIME_NONE) ? 0 : xing->duration;
- GST_BUFFER_DURATION (outbuf) = duration;
- GST_BUFFER_OFFSET (outbuf) = xing->byte_count;
- GST_BUFFER_OFFSET_END (outbuf) =
- xing->byte_count + GST_BUFFER_SIZE (outbuf);
-
- xing->byte_count += GST_BUFFER_SIZE (outbuf);
-
- if (xing->duration == GST_CLOCK_TIME_NONE)
- xing->duration = duration;
- else
- xing->duration += duration;
-
- if (GST_FLOW_IS_FATAL (ret = gst_pad_push (xing->srcpad, outbuf))) {
- GST_ERROR_OBJECT (xing, "Failed to push MP3 frame: %s",
- gst_flow_get_name (ret));
- return ret;
- }
- }
-
- return ret;
-}
-
-static gboolean
-gst_xing_mux_sink_event (GstPad * pad, GstEvent * event)
-{
- GstXingMux *xing;
- gboolean result;
-
- xing = GST_XING_MUX (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- if (xing->sent_xing) {
- GST_ERROR ("Already sent Xing header, dropping NEWSEGMENT event!");
- gst_event_unref (event);
- result = FALSE;
- } else {
- GstFormat fmt;
-
- gst_event_parse_new_segment (event, NULL, NULL, &fmt, NULL, NULL, NULL);
-
- if (fmt == GST_FORMAT_BYTES) {
- result = gst_pad_push_event (xing->srcpad, event);
- } else {
- gst_event_unref (event);
-
- event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- 0, GST_CLOCK_TIME_NONE, 0);
-
- result = gst_pad_push_event (xing->srcpad, event);
- }
- }
- break;
-
- case GST_EVENT_EOS:{
- GstEvent *n_event;
-
- GST_DEBUG_OBJECT (xing, "handling EOS event");
-
- if (xing->sent_xing) {
-
- n_event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
- 0, GST_CLOCK_TIME_NONE, 0);
-
- if (G_UNLIKELY (!gst_pad_push_event (xing->srcpad, n_event))) {
- GST_WARNING
- ("Failed to seek to position 0 for pushing the Xing header");
- } else {
- GstBuffer *header;
- GstFlowReturn ret;
-
- header = generate_xing_header (xing);
-
- if (header == NULL) {
- GST_ERROR ("Can't generate Xing header");
- } else {
-
- GST_INFO ("Writing real Xing header to beginning of stream");
-
- if (GST_FLOW_IS_FATAL (ret = gst_pad_push (xing->srcpad, header)))
- GST_WARNING ("Failed to push updated Xing header: %s\n",
- gst_flow_get_name (ret));
- }
- }
- }
- result = gst_pad_push_event (xing->srcpad, event);
- break;
- }
- default:
- result = gst_pad_event_default (pad, event);
- break;
- }
- gst_object_unref (GST_OBJECT (xing));
-
- return result;
-}
-
-
-static GstStateChangeReturn
-gst_xing_mux_change_state (GstElement * element, GstStateChange transition)
-{
- GstXingMux *xing;
- GstStateChangeReturn result;
-
- xing = GST_XING_MUX (element);
-
- result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- xing_reset (xing);
- break;
- default:
- break;
- }
-
- return result;
-}
--- a/gst_plugins_good/gst/mpegaudioparse/gstxingmux.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2006 Christophe Fergeau <teuf@gnome.org>
- * Copyright (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-
-#ifndef __GST_XINGMUX_H__
-#define __GST_XINGMUX_H__
-
-G_BEGIN_DECLS
-
-/* Standard macros for defining types for this element. */
-#define GST_TYPE_XING_MUX \
- (gst_xing_mux_get_type())
-#define GST_XING_MUX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XING_MUX,GstXingMux))
-#define GST_XING_MUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XING_MUX,GstXingMuxClass))
-#define GST_IS_XING_MUX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XING_MUX))
-#define GST_IS_XING_MUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XING_MUX))
-
-typedef struct _GstXingMux GstXingMux;
-typedef struct _GstXingMuxClass GstXingMuxClass;
-
-/* Definition of structure storing data for this element. */
-
-/**
- * GstXingMux:
- *
- * Opaque data structure.
- */
-struct _GstXingMux {
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
-
- /* < private > */
-
- GstAdapter *adapter;
- GstClockTime duration;
- guint64 byte_count;
- guint64 frame_count;
- GList *seek_table;
- gboolean sent_xing;
-
- /* Copy of the first frame header */
- guint32 first_header;
-};
-
-/* Standard definition defining a class for this element. */
-
-/**
- * GstXingMuxClass:
- *
- * Opaque data structure.
- */
-struct _GstXingMuxClass {
- GstElementClass parent_class;
-};
-
-/* Standard function returning type information. */
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_xing_mux_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_XINGMUX_H__ */
--- a/gst_plugins_good/gst/mpegaudioparse/plugin.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/* GStreamer
- * Copyright (C) <2008> Jan Schmidt <jan.schmidt@sun.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "../../config.h"
-#endif
-
-#include <gst/gst.h>
-#include "gstmpegaudioparse.h"
-#include "gstxingmux.h"
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "xingmux", GST_RANK_NONE,
- GST_TYPE_XING_MUX))
- return FALSE;
- if (!gst_element_register (plugin, "mp3parse", GST_RANK_PRIMARY + 1,
- GST_TYPE_MP3PARSE))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "mpegaudioparse",
- "MPEG-1 layer 1/2/3 audio stream elements",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
--- a/gst_plugins_good/gst/qtdemux/gstrtpxqtdepay.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,704 +0,0 @@
-/* GStreamer
- * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * based on http://developer.apple.com/quicktime/icefloe/dispatch026.html
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <gst/rtp/gstrtpbuffer.h>
-
-#include <string.h>
-#include "gstrtpxqtdepay.h"
-
-#define MAKE_TLV(a,b) (((a)<<8)|(b))
-
-#define TLV_sd MAKE_TLV ('s','d')
-#define TLV_qt MAKE_TLV ('q','t')
-#define TLV_ti MAKE_TLV ('t','i')
-#define TLV_ly MAKE_TLV ('l','y')
-#define TLV_vo MAKE_TLV ('v','o')
-#define TLV_mx MAKE_TLV ('m','x')
-#define TLV_tr MAKE_TLV ('t','r')
-#define TLV_tw MAKE_TLV ('t','w')
-#define TLV_th MAKE_TLV ('t','h')
-#define TLV_la MAKE_TLV ('l','a')
-#define TLV_rt MAKE_TLV ('r','t')
-#define TLV_gm MAKE_TLV ('g','m')
-#define TLV_oc MAKE_TLV ('o','c')
-#define TLV_cr MAKE_TLV ('c','r')
-#define TLV_du MAKE_TLV ('d','u')
-#define TLV_po MAKE_TLV ('p','o')
-
-#define QT_UINT32(a) (GST_READ_UINT32_BE(a))
-#define QT_UINT24(a) (GST_READ_UINT32_BE(a) >> 8)
-#define QT_UINT16(a) (GST_READ_UINT16_BE(a))
-#define QT_UINT8(a) (GST_READ_UINT8(a))
-#define QT_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0)
-#define QT_FP16(a) ((GST_READ_UINT16_BE(a))/256.0)
-#define QT_FOURCC(a) (GST_READ_UINT32_LE(a))
-#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4))
-
-#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1')
-#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C')
-
-GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug);
-#define GST_CAT_DEFAULT (rtpxqtdepay_debug)
-
-/* elementfactory information */
-static const GstElementDetails gst_rtp_xqtdepay_details =
-GST_ELEMENT_DETAILS ("RTP packet depayloader",
- "Codec/Depayloader/Network",
- "Extracts Quicktime audio/video from RTP packets",
- "Wim Taymans <wim@fluendo.com>");
-
-/* RtpXQTDepay signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
-};
-
-static GstStaticPadTemplate gst_rtp_xqt_depay_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-static GstStaticPadTemplate gst_rtp_xqt_depay_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp, "
- "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
- "media = (string) { \"audio\", \"video\" }, clock-rate = (int) [1, MAX], "
- "encoding-name = (string) { \"X-QT\", \"X-QUICKTIME\" }")
- );
-
-GST_BOILERPLATE (GstRtpXQTDepay, gst_rtp_xqt_depay, GstBaseRTPDepayload,
- GST_TYPE_BASE_RTP_DEPAYLOAD);
-
-static void gst_rtp_xqt_depay_finalize (GObject * object);
-
-static gboolean gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload,
- GstCaps * caps);
-static GstBuffer *gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload,
- GstBuffer * buf);
-
-static GstStateChangeReturn gst_rtp_xqt_depay_change_state (GstElement *
- element, GstStateChange transition);
-
-static void
-gst_rtp_xqt_depay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_xqt_depay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_xqt_depay_sink_template));
-
- gst_element_class_set_details (element_class, &gst_rtp_xqtdepay_details);
-}
-
-static void
-gst_rtp_xqt_depay_class_init (GstRtpXQTDepayClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_rtp_xqt_depay_finalize;
-
- gstelement_class->change_state = gst_rtp_xqt_depay_change_state;
-
- gstbasertpdepayload_class->set_caps = gst_rtp_xqt_depay_setcaps;
- gstbasertpdepayload_class->process = gst_rtp_xqt_depay_process;
-
- GST_DEBUG_CATEGORY_INIT (rtpxqtdepay_debug, "rtpxqtdepay", 0,
- "QT Media RTP Depayloader");
-}
-
-static void
-gst_rtp_xqt_depay_init (GstRtpXQTDepay * rtpxqtdepay,
- GstRtpXQTDepayClass * klass)
-{
- rtpxqtdepay->adapter = gst_adapter_new ();
-}
-
-static void
-gst_rtp_xqt_depay_finalize (GObject * object)
-{
- GstRtpXQTDepay *rtpxqtdepay;
-
- rtpxqtdepay = GST_RTP_XQT_DEPAY (object);
-
- g_object_unref (rtpxqtdepay->adapter);
- rtpxqtdepay->adapter = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static gboolean
-gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
- guint data_len)
-{
- gint len;
- guint32 fourcc;
-
- if (data_len < 8)
- goto too_short;
-
- len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- if (len > data_len)
- goto too_short;
-
- fourcc = QT_FOURCC (data + 4);
-
- GST_DEBUG_OBJECT (rtpxqtdepay, "parsing %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
- switch (fourcc) {
- case FOURCC_avc1:
- {
- guint32 chlen;
-
- if (len < 0x56)
- goto too_short;
- len -= 0x56;
- data += 0x56;
-
- /* find avcC */
- while (len >= 8) {
- chlen = QT_UINT32 (data);
- fourcc = QT_FOURCC (data + 4);
- if (fourcc == FOURCC_avcC) {
- GstBuffer *buf;
- gint size;
- GstCaps *caps;
-
- GST_DEBUG_OBJECT (rtpxqtdepay, "found avcC codec_data in sd, %u",
- chlen);
-
- /* parse, if found */
- if (chlen < len)
- size = chlen - 8;
- else
- size = len - 8;
-
- buf = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buf), data + 8, size);
- caps = gst_caps_new_simple ("video/x-h264",
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD (rtpxqtdepay)->srcpad, caps);
- gst_caps_unref (caps);
- break;
- }
- len -= chlen;
- data += chlen;
- }
- break;
- }
- default:
- break;
- }
- return TRUE;
-
- /* ERRORS */
-too_short:
- {
- return FALSE;
- }
-}
-
-static gboolean
-gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
-{
- GstStructure *structure;
- gint clock_rate = 90000; /* default */
-
- structure = gst_caps_get_structure (caps, 0);
-
- gst_structure_get_int (structure, "clock-rate", &clock_rate);
- depayload->clock_rate = clock_rate;
-
- return TRUE;
-}
-
-static GstBuffer *
-gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
-{
- GstRtpXQTDepay *rtpxqtdepay;
- GstBuffer *outbuf;
- gboolean m;
-
- rtpxqtdepay = GST_RTP_XQT_DEPAY (depayload);
-
- if (!gst_rtp_buffer_validate (buf))
- goto bad_packet;
-
- if (GST_BUFFER_IS_DISCONT (buf)) {
- /* discont, clear adapter and try to find a new packet start */
- gst_adapter_clear (rtpxqtdepay->adapter);
- rtpxqtdepay->need_resync = TRUE;
- GST_DEBUG_OBJECT (rtpxqtdepay, "we need resync");
- }
-
- m = gst_rtp_buffer_get_marker (buf);
- GST_LOG_OBJECT (rtpxqtdepay, "marker: %d", m);
-
- {
- gint payload_len;
- guint avail;
- guint8 *payload;
- guint32 timestamp;
- guint8 ver, pck;
- gboolean s, q, l, d;
-
- payload_len = gst_rtp_buffer_get_payload_len (buf);
- payload = gst_rtp_buffer_get_payload (buf);
-
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | VER |PCK|S|Q|L| RES |D| QuickTime Payload ID |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- if (payload_len <= 4)
- goto wrong_length;
-
- ver = (payload[0] & 0xf0) >> 4;
- if (ver > 1)
- goto wrong_version;
-
- pck = (payload[0] & 0x0c) >> 2;
- if (pck == 0)
- goto pck_reserved;
-
- s = (payload[0] & 0x02) != 0; /* contains sync sample */
- q = (payload[0] & 0x01) != 0; /* has payload description */
- l = (payload[1] & 0x80) != 0; /* has packet specific information description */
- d = (payload[2] & 0x80) != 0; /* don't cache info for payload id */
- /* id used for caching info */
- rtpxqtdepay->current_id = ((payload[2] & 0x7f) << 8) | payload[3];
-
- GST_LOG_OBJECT (rtpxqtdepay,
- "VER: %d, PCK: %d, S: %d, Q: %d, L: %d, D: %d, ID: %d", ver, pck, s, q,
- l, d, rtpxqtdepay->current_id);
-
- if (rtpxqtdepay->need_resync) {
- /* we need to find the boundary of a new packet after a DISCONT */
- if (pck != 3 || q) {
- /* non-fragmented packet or payload description present, packet starts
- * here. */
- rtpxqtdepay->need_resync = FALSE;
- } else {
- /* fragmented packet without description */
- if (m) {
- /* marker bit set, next packet is start of new one */
- rtpxqtdepay->need_resync = FALSE;
- }
- goto need_resync;
- }
- }
-
- payload += 4;
- payload_len -= 4;
-
- if (q) {
- gboolean k, f, a, z;
- guint pdlen, pdpadded;
- gint padding;
- guint32 media_type, timescale;
-
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |K|F|A|Z| RES | QuickTime Payload Desc Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . QuickTime Payload Desc Data ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- if (payload_len <= 4)
- goto wrong_length;
-
- k = (payload[0] & 0x80) != 0; /* keyframe */
- f = (payload[0] & 0x40) != 0; /* sparse */
- a = (payload[0] & 0x20) != 0; /* start of payload */
- z = (payload[0] & 0x10) != 0; /* end of payload */
- pdlen = (payload[2] << 8) | payload[3];
-
- if (pdlen < 12)
- goto wrong_length;
-
- /* calc padding */
- pdpadded = pdlen + 3;
- pdpadded -= pdpadded % 4;
- if (payload_len < pdpadded)
- goto wrong_length;
-
- padding = pdpadded - pdlen;
- GST_LOG_OBJECT (rtpxqtdepay,
- "K: %d, F: %d, A: %d, Z: %d, len: %d, padding %d", k, f, a, z, pdlen,
- padding);
-
- payload += 4;
- payload_len -= 4;
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QuickTime Media Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Timescale |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . QuickTime TLVs ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- media_type =
- (payload[0] << 24) | (payload[1] << 16) | (payload[2] << 8) |
- payload[3];
- timescale =
- (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) |
- payload[7];
-
- GST_LOG_OBJECT (rtpxqtdepay, "media_type: %c%c%c%c, timescale %u",
- payload[0], payload[1], payload[2], payload[3], timescale);
-
- payload += 8;
- payload_len -= 8;
- pdlen -= 12;
-
- /* parse TLV (type-length-value triplets */
- while (pdlen > 3) {
- guint16 tlv_len, tlv_type;
-
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QuickTime TLV Length | QuickTime TLV Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . QuickTime TLV Value ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tlv_len = (payload[0] << 8) | payload[1];
- tlv_type = (payload[2] << 8) | payload[3];
- pdlen -= 4;
- if (tlv_len > pdlen)
- goto wrong_length;
-
- GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2],
- payload[3], tlv_len);
-
- payload += 4;
- payload_len -= 4;
-
- switch (tlv_type) {
- case TLV_sd:
- /* Session description */
- if (!gst_rtp_quicktime_parse_sd (rtpxqtdepay, payload, tlv_len))
- goto unknown_format;
- rtpxqtdepay->have_sd = TRUE;
- break;
- case TLV_qt:
- case TLV_ti:
- case TLV_ly:
- case TLV_vo:
- case TLV_mx:
- case TLV_tr:
- case TLV_tw:
- case TLV_th:
- case TLV_la:
- case TLV_rt:
- case TLV_gm:
- case TLV_oc:
- case TLV_cr:
- case TLV_du:
- case TLV_po:
- default:
- break;
- }
-
- pdlen -= tlv_len;
- payload += tlv_len;
- payload_len -= tlv_len;
- }
- payload += padding;
- payload_len -= padding;
- }
-
- if (l) {
- guint ssilen, ssipadded;
- gint padding;
-
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RES | Sample-Specific Info Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . QuickTime TLVs ...
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- if (payload_len <= 4)
- goto wrong_length;
-
- ssilen = (payload[2] << 8) | payload[3];
- if (ssilen < 4)
- goto wrong_length;
-
- /* calc padding */
- ssipadded = ssilen + 3;
- ssipadded -= ssipadded % 4;
- if (payload_len < ssipadded)
- goto wrong_length;
-
- padding = ssipadded - ssilen;
- GST_LOG_OBJECT (rtpxqtdepay, "len: %d, padding %d", ssilen, padding);
-
- payload += 4;
- payload_len -= 4;
- ssilen -= 4;
-
- /* parse TLV (type-length-value triplets */
- while (ssilen > 3) {
- guint16 tlv_len, tlv_type;
-
- /* 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QuickTime TLV Length | QuickTime TLV Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . QuickTime TLV Value ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tlv_len = (payload[0] << 8) | payload[1];
- tlv_type = (payload[2] << 8) | payload[3];
- ssilen -= 4;
- if (tlv_len > ssilen)
- goto wrong_length;
-
- GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2],
- payload[3], tlv_len);
-
- payload += 4;
- payload_len -= 4;
-
- switch (tlv_type) {
- case TLV_sd:
- case TLV_qt:
- case TLV_ti:
- case TLV_ly:
- case TLV_vo:
- case TLV_mx:
- case TLV_tr:
- case TLV_tw:
- case TLV_th:
- case TLV_la:
- case TLV_rt:
- case TLV_gm:
- case TLV_oc:
- case TLV_cr:
- case TLV_du:
- case TLV_po:
- default:
- break;
- }
-
- ssilen -= tlv_len;
- payload += tlv_len;
- payload_len -= tlv_len;
- }
- payload += padding;
- payload_len -= padding;
- }
-
- timestamp = gst_rtp_buffer_get_timestamp (buf);
- rtpxqtdepay->previous_id = rtpxqtdepay->current_id;
-
- switch (pck) {
- case 1:
- {
- /* multiple samples per packet. */
- outbuf = gst_buffer_new_and_alloc (payload_len);
- memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
- return outbuf;
- }
- case 2:
- {
- guint slen, timestamp;
-
- /* multiple samples per packet.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |S| Reserved | Sample Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Sample Timestamp |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . Sample Data ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |S| Reserved | Sample Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Sample Timestamp |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . Sample Data ... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . ...... .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- while (payload_len > 8) {
- s = (payload[0] & 0x80) != 0; /* contains sync sample */
- slen = (payload[2] << 8) | payload[3];
- timestamp =
- (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) |
- payload[7];
-
- payload += 8;
- payload_len -= 8;
-
- if (slen > payload_len)
- slen = payload_len;
-
- outbuf = gst_buffer_new_and_alloc (slen);
- memcpy (GST_BUFFER_DATA (outbuf), payload, slen);
- if (!s)
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
-
- gst_base_rtp_depayload_push (depayload, outbuf);
-
- /* aligned on 32 bit boundary */
- slen = GST_ROUND_UP_4 (slen);
-
- payload += slen;
- payload_len -= slen;
- }
- break;
- }
- case 3:
- {
- /* one sample per packet, use adapter to combine based on marker bit. */
- outbuf = gst_buffer_new_and_alloc (payload_len);
- memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
-
- gst_adapter_push (rtpxqtdepay->adapter, outbuf);
-
- if (!m)
- goto done;
-
- avail = gst_adapter_available (rtpxqtdepay->adapter);
- outbuf = gst_adapter_take_buffer (rtpxqtdepay->adapter, avail);
-
- GST_DEBUG_OBJECT (rtpxqtdepay,
- "gst_rtp_xqt_depay_chain: pushing buffer of size %u", avail);
-
- return outbuf;
- }
- }
- }
-
-done:
- return NULL;
-
-bad_packet:
- {
- GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
- ("Packet did not validate."), (NULL));
- return NULL;
- }
-need_resync:
- {
- GST_DEBUG_OBJECT (rtpxqtdepay, "waiting for marker");
- return NULL;
- }
-wrong_version:
- {
- GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
- ("Unknown payload version."), (NULL));
- return NULL;
- }
-pck_reserved:
- {
- GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
- ("PCK reserved 0."), (NULL));
- return NULL;
- }
-wrong_length:
- {
- GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
- ("Wrong payload length."), (NULL));
- return NULL;
- }
-unknown_format:
- {
- GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
- ("Unknown payload format."), (NULL));
- return NULL;
- }
-}
-
-static GstStateChangeReturn
-gst_rtp_xqt_depay_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpXQTDepay *rtpxqtdepay;
- GstStateChangeReturn ret;
-
- rtpxqtdepay = GST_RTP_XQT_DEPAY (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- gst_adapter_clear (rtpxqtdepay->adapter);
- rtpxqtdepay->previous_id = -1;
- rtpxqtdepay->current_id = -1;
- rtpxqtdepay->need_resync = TRUE;
- rtpxqtdepay->have_sd = FALSE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_adapter_clear (rtpxqtdepay->adapter);
- default:
- break;
- }
- return ret;
-}
-
-gboolean
-gst_rtp_xqt_depay_plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, "rtpxqtdepay",
- GST_RANK_MARGINAL, GST_TYPE_RTP_XQT_DEPAY);
-}
--- a/gst_plugins_good/gst/qtdemux/gstrtpxqtdepay.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_RTP_XQT_DEPAY_H__
-#define __GST_RTP_XQT_DEPAY_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-#include <gst/rtp/gstbasertpdepayload.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_RTP_XQT_DEPAY \
- (gst_rtp_xqt_depay_get_type())
-#define GST_RTP_XQT_DEPAY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_XQT_DEPAY,GstRtpXQTDepay))
-#define GST_RTP_XQT_DEPAY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_XQT_DEPAY,GstRtpXQTDepayClass))
-#define GST_IS_RTP_XQT_DEPAY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_XQT_DEPAY))
-#define GST_IS_RTP_XQT_DEPAY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_XQT_DEPAY))
-
-typedef struct _GstRtpXQTDepay GstRtpXQTDepay;
-typedef struct _GstRtpXQTDepayClass GstRtpXQTDepayClass;
-
-struct _GstRtpXQTDepay
-{
- GstBaseRTPDepayload depayload;
-
- GstAdapter *adapter;
-
- gboolean need_resync;
- guint16 previous_id;
- guint16 current_id;
- gboolean have_sd;
-};
-
-struct _GstRtpXQTDepayClass
-{
- GstBaseRTPDepayloadClass parent_class;
-};
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_rtp_xqt_depay_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_RTP_XQT_DEPAY_H__ */
--- a/gst_plugins_good/gst/qtdemux/qtdemux.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6153 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
- * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
- * Copyright (C) <2007> Julien Moutte <julien@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-qtdemux
- *
- * Demuxes a .mov file into raw or compressed audio and/or video streams.
- *
- * This element supports both push and pull-based scheduling, depending on the
- * capabilities of the upstream elements.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch filesrc location=test.mov ! qtdemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
- * ]| Play (parse and decode) a .mov file and try to output it to
- * an automatically detected soundcard and videosink. If the MOV file contains
- * compressed audio or video data, this will only work if you have the
- * right decoder elements/plugins installed.
- * </refsect2>
- *
- * Last reviewed on 2006-12-29 (0.10.5)
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gst/gst-i18n-plugin.h"
-
-#include <gst/tag/tag.h>
-
-#include "qtdemux_types.h"
-#include "qtdemux_dump.h"
-#include "qtdemux_fourcc.h"
-#include "qtdemux.h"
-#include "qtpalette.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_ZLIB
-# include <zlib.h>
-#endif
-
-/* max. size considered 'sane' for non-mdat atoms */
-#define QTDEMUX_MAX_ATOM_SIZE (25*1024*1024)
-
-GST_DEBUG_CATEGORY (qtdemux_debug);
-
-/*typedef struct _QtNode QtNode; */
-typedef struct _QtDemuxSegment QtDemuxSegment;
-typedef struct _QtDemuxSample QtDemuxSample;
-
-/*struct _QtNode
-{
- guint32 type;
- guint8 *data;
- gint len;
-};*/
-
-struct _QtDemuxSample
-{
- guint32 size;
- guint64 offset;
- GstClockTimeDiff pts_offset; /* Add this value to timestamp to get the pts */
- guint64 timestamp; /* In GstClockTime */
- guint64 duration; /* in GstClockTime */
- gboolean keyframe; /* TRUE when this packet is a keyframe */
-};
-
-/*
- * Quicktime has tracks and segments. A track is a continuous piece of
- * multimedia content. The track is not always played from start to finish but
- * instead, pieces of the track are 'cut out' and played in sequence. This is
- * what the segments do.
- *
- * Inside the track we have keyframes (K) and delta frames. The track has its
- * own timing, which starts from 0 and extends to end. The position in the track
- * is called the media_time.
- *
- * The segments now describe the pieces that should be played from this track
- * and are basically tupples of media_time/duration/rate entries. We can have
- * multiple segments and they are all played after one another. An example:
- *
- * segment 1: media_time: 1 second, duration: 1 second, rate 1
- * segment 2: media_time: 3 second, duration: 2 second, rate 2
- *
- * To correctly play back this track, one must play: 1 second of media starting
- * from media_time 1 followed by 2 seconds of media starting from media_time 3
- * at a rate of 2.
- *
- * Each of the segments will be played at a specific time, the first segment at
- * time 0, the second one after the duration of the first one, etc.. Note that
- * the time in resulting playback is not identical to the media_time of the
- * track anymore.
- *
- * Visually, assuming the track has 4 second of media_time:
- *
- * (a) (b) (c) (d)
- * .-----------------------------------------------------------.
- * track: | K.....K.........K........K.......K.......K...........K... |
- * '-----------------------------------------------------------'
- * 0 1 2 3 4
- * .------------^ ^ .----------^ ^
- * / .-------------' / .------------------'
- * / / .-----' /
- * .--------------. .--------------.
- * | segment 1 | | segment 2 |
- * '--------------' '--------------'
- *
- * The challenge here is to cut out the right pieces of the track for each of
- * the playback segments. This fortunatly can easily be done with the SEGMENT
- * events of gstreamer.
- *
- * For playback of segment 1, we need to provide the decoder with the keyframe
- * (a), in the above figure, but we must instruct it only to output the decoded
- * data between second 1 and 2. We do this with a SEGMENT event for 1 to 2, time
- * position set to the time of the segment: 0.
- *
- * We then proceed to push data from keyframe (a) to frame (b). The decoder
- * decodes but clips all before media_time 1.
- *
- * After finishing a segment, we push out a new SEGMENT event with the clipping
- * boundaries of the new data.
- *
- * This is a good usecase for the GStreamer accumulated SEGMENT events.
- */
-
-struct _QtDemuxSegment
-{
- /* global time and duration, all gst time */
- guint64 time;
- guint64 stop_time;
- guint64 duration;
- /* media time of trak, all gst time */
- guint64 media_start;
- guint64 media_stop;
- gdouble rate;
-};
-
-struct _QtDemuxStream
-{
- GstPad *pad;
-
- /* stream type */
- guint32 subtype;
- GstCaps *caps;
- guint32 fourcc;
-
- /* duration/scale */
- guint64 duration; /* in timescale */
- guint32 timescale;
-
- /* our samples */
- guint32 n_samples;
- QtDemuxSample *samples;
- gboolean all_keyframe; /* TRUE when all samples are keyframes (no stss) */
- guint32 min_duration; /* duration in timescale of first sample, used for figuring out
- the framerate, in timescale units */
-
- /* if we use chunks or samples */
- gboolean sampled;
- guint padding;
-
- /* video info */
- gint width;
- gint height;
- /* aspect ratio */
- gint display_width;
- gint display_height;
- gint par_w;
- gint par_h;
- /* Numerator/denominator framerate */
- gint fps_n;
- gint fps_d;
- guint16 bits_per_sample;
- guint16 color_table_id;
-
- /* audio info */
- gdouble rate;
- gint n_channels;
- guint samples_per_packet;
- guint samples_per_frame;
- guint bytes_per_packet;
- guint bytes_per_sample;
- guint bytes_per_frame;
- guint compression;
-
- /* when a discontinuity is pending */
- gboolean discont;
-
- /* list of buffers to push first */
- GSList *buffers;
-
- /* if we need to clip this buffer. This is only needed for uncompressed
- * data */
- gboolean need_clip;
-
- /* current position */
- guint32 segment_index;
- guint32 sample_index;
- guint64 time_position; /* in gst time */
-
- /* the Gst segment we are processing out, used for clipping */
- GstSegment segment;
-
- /* last GstFlowReturn */
- GstFlowReturn last_ret;
-
- /* quicktime segments */
- guint32 n_segments;
- QtDemuxSegment *segments;
- guint32 from_sample;
- guint32 to_sample;
-
- gboolean sent_eos;
-};
-
-enum QtDemuxState
-{
- QTDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */
- QTDEMUX_STATE_HEADER, /* Parsing the header */
- QTDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */
- QTDEMUX_STATE_BUFFER_MDAT /* Buffering the mdat atom */
-};
-
-static GNode *qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc);
-static GNode *qtdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc);
-
-static const GstElementDetails gst_qtdemux_details =
-GST_ELEMENT_DETAILS ("QuickTime demuxer",
- "Codec/Demuxer",
- "Demultiplex a QuickTime file into audio and video streams",
- "David Schleef <ds@schleef.org>, Wim Taymans <wim@fluendo.com>");
-
-static GstStaticPadTemplate gst_qtdemux_sink_template =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/quicktime; video/mj2; audio/x-m4a; "
- "application/x-3gp")
- );
-
-static GstStaticPadTemplate gst_qtdemux_videosrc_template =
-GST_STATIC_PAD_TEMPLATE ("video_%02d",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS_ANY);
-
-static GstStaticPadTemplate gst_qtdemux_audiosrc_template =
-GST_STATIC_PAD_TEMPLATE ("audio_%02d",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS_ANY);
-
-static GstStaticPadTemplate gst_qtdemux_subpsrc_template =
-GST_STATIC_PAD_TEMPLATE ("subp_%02d",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS_ANY);
-
-static GstElementClass *parent_class = NULL;
-
-static void gst_qtdemux_class_init (GstQTDemuxClass * klass);
-static void gst_qtdemux_base_init (GstQTDemuxClass * klass);
-static void gst_qtdemux_init (GstQTDemux * quicktime_demux);
-static void gst_qtdemux_dispose (GObject * object);
-
-static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
- GstStateChange transition);
-static gboolean qtdemux_sink_activate (GstPad * sinkpad);
-static gboolean qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active);
-static gboolean qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active);
-
-static void gst_qtdemux_loop (GstPad * pad);
-static GstFlowReturn gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf);
-static gboolean gst_qtdemux_handle_sink_event (GstPad * pad, GstEvent * event);
-
-static gboolean qtdemux_parse_moov (GstQTDemux * qtdemux, const guint8 * buffer,
- int length);
-static gboolean qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node,
- const guint8 * buffer, int length);
-static gboolean qtdemux_parse_tree (GstQTDemux * qtdemux);
-
-static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux,
- QtDemuxStream * stream, GNode * esds, GstTagList * list);
-static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux,
- QtDemuxStream * stream, guint32 fourcc, const guint8 * stsd_data,
- gchar ** codec_name);
-static GstCaps *qtdemux_audio_caps (GstQTDemux * qtdemux,
- QtDemuxStream * stream, guint32 fourcc, const guint8 * data, int len,
- gchar ** codec_name);
-static GstCaps *qtdemux_subp_caps (GstQTDemux * qtdemux,
- QtDemuxStream * stream, guint32 fourcc, const guint8 * data,
- gchar ** codec_name);
-
-GType
-gst_qtdemux_get_type (void)
-{
- static GType qtdemux_type = 0;
-
- if (G_UNLIKELY (!qtdemux_type)) {
- static const GTypeInfo qtdemux_info = {
- sizeof (GstQTDemuxClass),
- (GBaseInitFunc) gst_qtdemux_base_init, NULL,
- (GClassInitFunc) gst_qtdemux_class_init,
- NULL, NULL, sizeof (GstQTDemux), 0,
- (GInstanceInitFunc) gst_qtdemux_init,
- };
-
- qtdemux_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstQTDemux", &qtdemux_info,
- 0);
- }
- return qtdemux_type;
-}
-
-static void
-gst_qtdemux_base_init (GstQTDemuxClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_videosrc_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_audiosrc_template));
- gst_element_class_set_details (element_class, &gst_qtdemux_details);
-
- GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin");
-}
-
-static void
-gst_qtdemux_class_init (GstQTDemuxClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->dispose = gst_qtdemux_dispose;
-
- gstelement_class->change_state = gst_qtdemux_change_state;
-}
-
-static void
-gst_qtdemux_init (GstQTDemux * qtdemux)
-{
- qtdemux->sinkpad =
- gst_pad_new_from_static_template (&gst_qtdemux_sink_template, "sink");
- gst_pad_set_activate_function (qtdemux->sinkpad, qtdemux_sink_activate);
- gst_pad_set_activatepull_function (qtdemux->sinkpad,
- qtdemux_sink_activate_pull);
- gst_pad_set_activatepush_function (qtdemux->sinkpad,
- qtdemux_sink_activate_push);
- gst_pad_set_chain_function (qtdemux->sinkpad, gst_qtdemux_chain);
- gst_pad_set_event_function (qtdemux->sinkpad, gst_qtdemux_handle_sink_event);
- gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), qtdemux->sinkpad);
-
- qtdemux->state = QTDEMUX_STATE_INITIAL;
- /* FIXME, use segment last_stop for this */
- qtdemux->last_ts = GST_CLOCK_TIME_NONE;
- qtdemux->pullbased = FALSE;
- qtdemux->neededbytes = 16;
- qtdemux->todrop = 0;
- qtdemux->adapter = gst_adapter_new ();
- qtdemux->offset = 0;
- qtdemux->mdatoffset = GST_CLOCK_TIME_NONE;
- qtdemux->mdatbuffer = NULL;
- gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
-}
-
-static void
-gst_qtdemux_dispose (GObject * object)
-{
- GstQTDemux *qtdemux = GST_QTDEMUX (object);
-
- if (qtdemux->adapter) {
- g_object_unref (G_OBJECT (qtdemux->adapter));
- qtdemux->adapter = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static GstFlowReturn
-gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
- GstBuffer ** buf)
-{
- GstFlowReturn flow;
-
- /* Sanity check: catch bogus sizes (fuzzed/broken files) */
- if (G_UNLIKELY (size > QTDEMUX_MAX_ATOM_SIZE)) {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file is invalid and cannot be played.")),
- ("atom has bogus size %" G_GUINT64_FORMAT, size));
- return GST_FLOW_ERROR;
- }
-
- flow = gst_pad_pull_range (qtdemux->sinkpad, offset, size, buf);
-
- if (G_UNLIKELY (flow != GST_FLOW_OK))
- return flow;
-
- /* Catch short reads - we don't want any partial atoms */
- if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size)) {
- GST_WARNING_OBJECT (qtdemux, "short read: %u < %" G_GUINT64_FORMAT,
- GST_BUFFER_SIZE (*buf), size);
- gst_buffer_unref (*buf);
- *buf = NULL;
- return GST_FLOW_UNEXPECTED;
- }
-
- return flow;
-}
-
-#if 0
-static gboolean
-gst_qtdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
- GstFormat * dest_format, gint64 * dest_value)
-{
- gboolean res = TRUE;
- QtDemuxStream *stream = gst_pad_get_element_private (pad);
-
- if (stream->subtype == GST_MAKE_FOURCC ('v', 'i', 'd', 'e') &&
- (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
- return FALSE;
-
- switch (src_format) {
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- *dest_value = src_value * 1; /* FIXME */
- break;
- case GST_FORMAT_DEFAULT:
- *dest_value = src_value * 1; /* FIXME */
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_BYTES:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = src_value * 1; /* FIXME */
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- case GST_FORMAT_DEFAULT:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = src_value * 1; /* FIXME */
- break;
- default:
- res = FALSE;
- break;
- }
- break;
- default:
- res = FALSE;
- }
-
- return res;
-}
-#endif
-
-static const GstQueryType *
-gst_qtdemux_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType src_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_SEEKING,
- 0
- };
-
- return src_types;
-}
-
-static gboolean
-gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
-{
- gboolean res = TRUE;
-
- *duration = GST_CLOCK_TIME_NONE;
-
- if (qtdemux->duration != 0) {
- if (qtdemux->duration != G_MAXINT32 && qtdemux->timescale != 0) {
- *duration = gst_util_uint64_scale (qtdemux->duration,
- GST_SECOND, qtdemux->timescale);
- }
- }
- return res;
-}
-
-static gboolean
-gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
-{
- gboolean res = FALSE;
- GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
-
- GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:
- if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.last_stop)) {
- gst_query_set_position (query, GST_FORMAT_TIME,
- qtdemux->segment.last_stop);
- res = TRUE;
- }
- break;
- case GST_QUERY_DURATION:{
- GstFormat fmt;
-
- gst_query_parse_duration (query, &fmt, NULL);
- if (fmt == GST_FORMAT_TIME) {
- gint64 duration = -1;
-
- gst_qtdemux_get_duration (qtdemux, &duration);
- if (duration > 0) {
- gst_query_set_duration (query, GST_FORMAT_TIME, duration);
- res = TRUE;
- }
- }
- break;
- }
- case GST_QUERY_SEEKING:{
- GstFormat fmt;
- gboolean seekable;
-
- gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
- if (fmt == GST_FORMAT_TIME) {
- gint64 duration = -1;
-
- gst_qtdemux_get_duration (qtdemux, &duration);
- seekable = TRUE;
- if (!qtdemux->pullbased) {
- GstQuery *q;
-
- /* we might be able with help from upstream */
- seekable = FALSE;
- q = gst_query_new_seeking (GST_FORMAT_BYTES);
- if (gst_pad_peer_query (qtdemux->sinkpad, q)) {
- gst_query_parse_seeking (q, &fmt, &seekable, NULL, NULL);
- GST_LOG_OBJECT (qtdemux, "upstream BYTE seekable %d", seekable);
- }
- gst_query_unref (q);
- }
- gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, duration);
- res = TRUE;
- }
- break;
- }
- default:
- res = gst_pad_query_default (pad, query);
- break;
- }
-
- gst_object_unref (qtdemux);
-
- return res;
-}
-
-/* push event on all source pads; takes ownership of the event */
-static void
-gst_qtdemux_push_event (GstQTDemux * qtdemux, GstEvent * event)
-{
- guint n;
-
- GST_DEBUG_OBJECT (qtdemux, "pushing %s event on all source pads",
- GST_EVENT_TYPE_NAME (event));
-
- for (n = 0; n < qtdemux->n_streams; n++) {
- GstPad *pad;
-
- if ((pad = qtdemux->streams[n]->pad))
- gst_pad_push_event (pad, gst_event_ref (event));
- }
- gst_event_unref (event);
-}
-
-/* push a pending newsegment event, if any from the streaming thread */
-static void
-gst_qtdemux_push_pending_newsegment (GstQTDemux * qtdemux)
-{
- if (qtdemux->pending_newsegment) {
- gst_qtdemux_push_event (qtdemux, qtdemux->pending_newsegment);
- qtdemux->pending_newsegment = NULL;
- }
-}
-
-typedef struct
-{
- guint64 media_time;
-} FindData;
-
-static gint
-find_func (QtDemuxSample * s1, guint64 * media_time, gpointer user_data)
-{
- if (s1->timestamp > *media_time)
- return 1;
-
- return -1;
-}
-
-/* find the index of the sample that includes the data for @media_time
- *
- * Returns the index of the sample.
- */
-static guint32
-gst_qtdemux_find_index (GstQTDemux * qtdemux, QtDemuxStream * str,
- guint64 media_time)
-{
- QtDemuxSample *result;
- guint32 index;
-
- result = gst_util_array_binary_search (str->samples, str->n_samples,
- sizeof (QtDemuxSample), (GCompareDataFunc) find_func,
- GST_SEARCH_MODE_BEFORE, &media_time, NULL);
-
- if (G_LIKELY (result))
- index = result - str->samples;
- else
- index = 0;
-
- return index;
-}
-
-/* find the index of the keyframe needed to decode the sample at @index
- * of stream @str.
- *
- * Returns the index of the keyframe.
- */
-static guint32
-gst_qtdemux_find_keyframe (GstQTDemux * qtdemux, QtDemuxStream * str,
- guint32 index)
-{
- guint32 new_index = index;
-
- if (index >= str->n_samples) {
- new_index = str->n_samples;
- goto beach;
- }
-
- /* all keyframes, return index */
- if (str->all_keyframe) {
- new_index = index;
- goto beach;
- }
-
- /* else go back until we have a keyframe */
- while (TRUE) {
- if (str->samples[new_index].keyframe)
- break;
-
- if (new_index == 0)
- break;
-
- new_index--;
- }
-
-beach:
- GST_DEBUG_OBJECT (qtdemux, "searching for keyframe index before index %u "
- "gave %u", index, new_index);
-
- return new_index;
-}
-
-/* find the segment for @time_position for @stream
- *
- * Returns -1 if the segment cannot be found.
- */
-static guint32
-gst_qtdemux_find_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
- guint64 time_position)
-{
- gint i;
- guint32 seg_idx;
-
- GST_LOG_OBJECT (qtdemux, "finding segment for %" GST_TIME_FORMAT,
- GST_TIME_ARGS (time_position));
-
- /* find segment corresponding to time_position if we are looking
- * for a segment. */
- seg_idx = -1;
- for (i = 0; i < stream->n_segments; i++) {
- QtDemuxSegment *segment = &stream->segments[i];
-
- GST_LOG_OBJECT (qtdemux,
- "looking at segment %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
- GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->stop_time));
-
- /* For the last segment we include stop_time in the last segment */
- if (i < stream->n_segments - 1) {
- if (segment->time <= time_position && time_position < segment->stop_time) {
- GST_LOG_OBJECT (qtdemux, "segment %d matches", i);
- seg_idx = i;
- break;
- }
- } else {
- if (segment->time <= time_position && time_position <= segment->stop_time) {
- GST_LOG_OBJECT (qtdemux, "segment %d matches", i);
- seg_idx = i;
- break;
- }
- }
- }
- return seg_idx;
-}
-
-/* move the stream @str to the sample position @index.
- *
- * Updates @str->sample_index and marks discontinuity if needed.
- */
-static void
-gst_qtdemux_move_stream (GstQTDemux * qtdemux, QtDemuxStream * str,
- guint32 index)
-{
- /* no change needed */
- if (index == str->sample_index)
- return;
-
- GST_DEBUG_OBJECT (qtdemux, "moving to sample %u of %u", index,
- str->n_samples);
-
- /* position changed, we have a discont */
- str->sample_index = index;
- /* Each time we move in the stream we store the position where we are
- * starting from */
- str->from_sample = index;
- str->discont = TRUE;
-}
-
-static void
-gst_qtdemux_adjust_seek (GstQTDemux * qtdemux, gint64 desired_time,
- gint64 * key_time, gint64 * key_offset)
-{
- guint64 min_offset;
- gint64 min_byte_offset = -1;
- gint n;
-
- min_offset = desired_time;
-
- /* for each stream, find the index of the sample in the segment
- * and move back to the previous keyframe. */
- for (n = 0; n < qtdemux->n_streams; n++) {
- QtDemuxStream *str;
- guint32 index, kindex;
- guint32 seg_idx;
- guint64 media_start;
- guint64 media_time;
- guint64 seg_time;
- QtDemuxSegment *seg;
-
- str = qtdemux->streams[n];
-
- seg_idx = gst_qtdemux_find_segment (qtdemux, str, desired_time);
- GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx);
-
- /* segment not found, continue with normal flow */
- if (seg_idx == -1)
- continue;
-
- /* get segment and time in the segment */
- seg = &str->segments[seg_idx];
- seg_time = desired_time - seg->time;
-
- /* get the media time in the segment */
- media_start = seg->media_start + seg_time;
-
- /* get the index of the sample with media time */
- index = gst_qtdemux_find_index (qtdemux, str, media_start);
- GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
- GST_TIME_ARGS (media_start), index);
-
- /* find previous keyframe */
- kindex = gst_qtdemux_find_keyframe (qtdemux, str, index);
-
- /* if the keyframe is at a different position, we need to update the
- * requested seek time */
- if (index != kindex) {
- index = kindex;
-
- /* get timestamp of keyframe */
- media_time = str->samples[kindex].timestamp;
- GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT,
- kindex, GST_TIME_ARGS (media_time));
-
- /* keyframes in the segment get a chance to change the
- * desired_offset. keyframes out of the segment are
- * ignored. */
- if (media_time >= seg->media_start) {
- guint64 seg_time;
-
- /* this keyframe is inside the segment, convert back to
- * segment time */
- seg_time = (media_time - seg->media_start) + seg->time;
- if (seg_time < min_offset)
- min_offset = seg_time;
- }
- }
-
- if (min_byte_offset < 0 || str->samples[index].offset < min_byte_offset)
- min_byte_offset = str->samples[index].offset;
- }
-
- if (key_time)
- *key_time = min_offset;
- if (key_offset)
- *key_offset = min_byte_offset;
-}
-
-static gboolean
-gst_qtdemux_convert_seek (GstPad * pad, GstFormat * format,
- GstSeekType cur_type, gint64 * cur, GstSeekType stop_type, gint64 * stop)
-{
- gboolean res;
- GstFormat fmt;
-
- g_return_val_if_fail (format != NULL, FALSE);
- g_return_val_if_fail (cur != NULL, FALSE);
- g_return_val_if_fail (stop != NULL, FALSE);
-
- if (*format == GST_FORMAT_TIME)
- return TRUE;
-
- fmt = GST_FORMAT_TIME;
- res = TRUE;
- if (cur_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, *format, *cur, &fmt, cur);
- if (res && stop_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, *format, *stop, &fmt, stop);
-
- if (res)
- *format = GST_FORMAT_TIME;
-
- return res;
-}
-
-/* perform seek in push based mode:
- find BYTE position to move to based on time and delegate to upstream
-*/
-static gboolean
-gst_qtdemux_do_push_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
-{
- gdouble rate;
- GstFormat format;
- GstSeekFlags flags;
- GstSeekType cur_type, stop_type;
- gint64 cur, stop;
- gboolean res;
- gint64 byte_cur;
-
- GST_DEBUG_OBJECT (qtdemux, "doing push-based seek");
-
- gst_event_parse_seek (event, &rate, &format, &flags,
- &cur_type, &cur, &stop_type, &stop);
-
- if (stop_type != GST_SEEK_TYPE_NONE)
- goto unsupported_seek;
- stop = -1;
-
- /* only forward streaming and seeking is possible */
- if (rate <= 0)
- goto unsupported_seek;
-
- /* convert to TIME if needed and possible */
- if (!gst_qtdemux_convert_seek (pad, &format, cur_type, &cur,
- stop_type, &stop))
- goto no_format;
-
- /* find reasonable corresponding BYTE position,
- * also try to mind about keyframes, since we can not go back a bit for them
- * later on */
- gst_qtdemux_adjust_seek (qtdemux, cur, NULL, &byte_cur);
-
- if (byte_cur == -1)
- goto abort_seek;
-
- GST_DEBUG_OBJECT (qtdemux, "Pushing BYTE seek rate %g, "
- "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, byte_cur,
- stop);
- /* BYTE seek event */
- event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
- stop_type, stop);
- res = gst_pad_push_event (qtdemux->sinkpad, event);
-
- return res;
-
- /* ERRORS */
-abort_seek:
- {
- GST_DEBUG_OBJECT (qtdemux, "could not determine byte position to seek to, "
- "seek aborted.");
- return FALSE;
- }
-unsupported_seek:
- {
- GST_DEBUG_OBJECT (qtdemux, "unsupported seek, seek aborted.");
- return FALSE;
- }
-no_format:
- {
- GST_DEBUG_OBJECT (qtdemux, "unsupported format given, seek aborted.");
- return FALSE;
- }
-}
-
-/* perform the seek.
- *
- * We set all segment_indexes in the streams to unknown and
- * adjust the time_position to the desired position. this is enough
- * to trigger a segment switch in the streaming thread to start
- * streaming from the desired position.
- *
- * Keyframe seeking is a little more complicated when dealing with
- * segments. Ideally we want to move to the previous keyframe in
- * the segment but there might not be a keyframe in the segment. In
- * fact, none of the segments could contain a keyframe. We take a
- * practical approach: seek to the previous keyframe in the segment,
- * if there is none, seek to the beginning of the segment.
- *
- * Called with STREAM_LOCK
- */
-static gboolean
-gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment)
-{
- gint64 desired_offset;
- gint n;
-
- desired_offset = segment->last_stop;
-
- GST_DEBUG_OBJECT (qtdemux, "seeking to %" GST_TIME_FORMAT,
- GST_TIME_ARGS (desired_offset));
-
- if (segment->flags & GST_SEEK_FLAG_KEY_UNIT) {
- gint64 min_offset;
-
- gst_qtdemux_adjust_seek (qtdemux, desired_offset, &min_offset, NULL);
- GST_DEBUG_OBJECT (qtdemux, "keyframe seek, align to %"
- GST_TIME_FORMAT, GST_TIME_ARGS (min_offset));
- desired_offset = min_offset;
- }
-
- /* and set all streams to the final position */
- for (n = 0; n < qtdemux->n_streams; n++) {
- QtDemuxStream *stream = qtdemux->streams[n];
-
- stream->time_position = desired_offset;
- stream->sample_index = -1;
- stream->segment_index = -1;
- stream->last_ret = GST_FLOW_OK;
- stream->sent_eos = FALSE;
- }
- segment->last_stop = desired_offset;
- segment->time = desired_offset;
-
- /* we stop at the end */
- if (segment->stop == -1)
- segment->stop = segment->duration;
-
- return TRUE;
-}
-
-/* do a seek in pull based mode */
-static gboolean
-gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
-{
- gdouble rate;
- GstFormat format;
- GstSeekFlags flags;
- GstSeekType cur_type, stop_type;
- gint64 cur, stop;
- gboolean flush;
- gboolean update;
- GstSegment seeksegment;
- int i;
-
- if (event) {
- GST_DEBUG_OBJECT (qtdemux, "doing seek with event");
-
- gst_event_parse_seek (event, &rate, &format, &flags,
- &cur_type, &cur, &stop_type, &stop);
-
- /* we have to have a format as the segment format. Try to convert
- * if not. */
- if (!gst_qtdemux_convert_seek (pad, &format, cur_type, &cur,
- stop_type, &stop))
- goto no_format;
-
- GST_DEBUG_OBJECT (qtdemux, "seek format %s", gst_format_get_name (format));
- } else {
- GST_DEBUG_OBJECT (qtdemux, "doing seek without event");
- flags = 0;
- }
-
- flush = flags & GST_SEEK_FLAG_FLUSH;
-
- /* stop streaming, either by flushing or by pausing the task */
- if (flush) {
- /* unlock upstream pull_range */
- gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_start ());
- /* make sure out loop function exits */
- gst_qtdemux_push_event (qtdemux, gst_event_new_flush_start ());
- } else {
- /* non flushing seek, pause the task */
- gst_pad_pause_task (qtdemux->sinkpad);
- }
-
- /* wait for streaming to finish */
- GST_PAD_STREAM_LOCK (qtdemux->sinkpad);
-
- /* copy segment, we need this because we still need the old
- * segment when we close the current segment. */
- memcpy (&seeksegment, &qtdemux->segment, sizeof (GstSegment));
-
- if (event) {
- /* configure the segment with the seek variables */
- GST_DEBUG_OBJECT (qtdemux, "configuring seek");
- gst_segment_set_seek (&seeksegment, rate, format, flags,
- cur_type, cur, stop_type, stop, &update);
- }
-
- /* now do the seek, this actually never returns FALSE */
- gst_qtdemux_perform_seek (qtdemux, &seeksegment);
-
- /* prepare for streaming again */
- if (flush) {
- gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop ());
- gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop ());
- } else if (qtdemux->segment_running) {
- /* we are running the current segment and doing a non-flushing seek,
- * close the segment first based on the last_stop. */
- GST_DEBUG_OBJECT (qtdemux, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, qtdemux->segment.start,
- qtdemux->segment.last_stop);
-
- if (qtdemux->segment.rate >= 0) {
- /* FIXME, rate is the product of the global rate and the (quicktime)
- * segment rate. */
- qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
- qtdemux->segment.rate, qtdemux->segment.format,
- qtdemux->segment.start, qtdemux->segment.last_stop,
- qtdemux->segment.time);
- } else { /* For Reverse Playback */
- guint64 stop;
-
- if ((stop = qtdemux->segment.stop) == -1)
- stop = qtdemux->segment.duration;
- /* for reverse playback, we played from stop to last_stop. */
- qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
- qtdemux->segment.rate, qtdemux->segment.format,
- qtdemux->segment.last_stop, stop, qtdemux->segment.last_stop);
- }
- }
-
- /* commit the new segment */
- memcpy (&qtdemux->segment, &seeksegment, sizeof (GstSegment));
-
- if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
- gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
- gst_message_new_segment_start (GST_OBJECT_CAST (qtdemux),
- qtdemux->segment.format, qtdemux->segment.last_stop));
- }
-
- /* restart streaming, NEWSEGMENT will be sent from the streaming
- * thread. */
- qtdemux->segment_running = TRUE;
- for (i = 0; i < qtdemux->n_streams; i++)
- qtdemux->streams[i]->last_ret = GST_FLOW_OK;
-
- gst_pad_start_task (qtdemux->sinkpad, (GstTaskFunction) gst_qtdemux_loop,
- qtdemux->sinkpad);
-
- GST_PAD_STREAM_UNLOCK (qtdemux->sinkpad);
-
- return TRUE;
-
- /* ERRORS */
-no_format:
- {
- GST_DEBUG_OBJECT (qtdemux, "unsupported format given, seek aborted.");
- return FALSE;
- }
-}
-
-static gboolean
-gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
-{
- gboolean res = TRUE;
- GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEEK:
- if (qtdemux->pullbased) {
- res = gst_qtdemux_do_seek (qtdemux, pad, event);
- } else if (qtdemux->state == QTDEMUX_STATE_MOVIE && qtdemux->n_streams) {
- res = gst_qtdemux_do_push_seek (qtdemux, pad, event);
- } else {
- GST_DEBUG_OBJECT (qtdemux,
- "ignoring seek in push mode in current state");
- res = FALSE;
- }
- gst_event_unref (event);
- break;
- case GST_EVENT_QOS:
- case GST_EVENT_NAVIGATION:
- res = FALSE;
- gst_event_unref (event);
- break;
- default:
- res = gst_pad_event_default (pad, event);
- break;
- }
-
- gst_object_unref (qtdemux);
-
- return res;
-}
-
-/* stream/index return sample that is min/max w.r.t. byte position,
- * time is min/max w.r.t. time of samples,
- * the latter need not be time of the former sample */
-static void
-gst_qtdemux_find_sample (GstQTDemux * qtdemux, gint64 byte_pos, gboolean fw,
- gboolean set, QtDemuxStream ** _stream, gint * _index, gint64 * _time)
-{
- gint i, n, index;
- gint64 time, min_time;
- QtDemuxStream *stream;
-
- min_time = -1;
- stream = NULL;
- index = -1;
-
- for (n = 0; n < qtdemux->n_streams; ++n) {
- QtDemuxStream *str;
- gint inc;
- gboolean set_sample;
-
-
- str = qtdemux->streams[n];
- set_sample = !set;
-
- if (fw) {
- i = 0;
- inc = 1;
- } else {
- i = str->n_samples - 1;
- inc = -1;
- }
- for (; (i >= 0) && (i < str->n_samples); i += inc) {
- if (str->samples[i].size &&
- ((fw && (str->samples[i].offset >= byte_pos)) ||
- (!fw &&
- (str->samples[i].offset + str->samples[i].size <=
- byte_pos)))) {
- /* move stream to first available sample */
- if (set) {
- gst_qtdemux_move_stream (qtdemux, str, i);
- set_sample = TRUE;
- }
- /* determine min/max time */
- time = str->samples[i].timestamp + str->samples[i].pts_offset;
- if (min_time == -1 || (fw && min_time > time) ||
- (!fw && min_time < time)) {
- min_time = time;
- }
- /* determine stream with leading sample, to get its position */
- /* only needed in fw case */
- if (fw && (!stream ||
- str->samples[i].offset < stream->samples[index].offset)) {
- stream = str;
- index = i;
- }
- break;
- }
- }
- /* no sample for this stream, mark eos */
- if (!set_sample)
- gst_qtdemux_move_stream (qtdemux, str, str->n_samples);
- }
-
- if (_time)
- *_time = min_time;
- if (_stream)
- *_stream = stream;
- if (_index)
- *_index = index;
-}
-
-static gboolean
-gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
-{
- GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
- gboolean res;
-
- GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- {
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time, offset = 0;
- QtDemuxStream *stream;
- gint idx;
- gboolean update;
- GstSegment segment;
-
- /* some debug output */
- gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
- gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
- start, stop, time);
- GST_DEBUG_OBJECT (demux,
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
- &segment);
-
- /* chain will send initial newsegment after pads have been added */
- if (demux->state != QTDEMUX_STATE_MOVIE || !demux->n_streams) {
- GST_DEBUG_OBJECT (demux, "still starting, eating event");
- goto exit;
- }
-
- /* we only expect a BYTE segment, e.g. following a seek */
- if (format == GST_FORMAT_BYTES) {
- if (start > 0) {
- offset = start;
- gst_qtdemux_find_sample (demux, start, TRUE, FALSE, NULL, NULL,
- &start);
- start = MAX (start, 0);
- }
- if (stop > 0) {
- gst_qtdemux_find_sample (demux, stop, FALSE, FALSE, NULL, NULL,
- &stop);
- stop = MAX (stop, 0);
- }
- } else {
- GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
- goto exit;
- }
-
- /* accept upstream's notion of segment and distribute along */
- gst_segment_set_newsegment_full (&demux->segment, update, rate, arate,
- GST_FORMAT_TIME, start, stop, start);
- GST_DEBUG_OBJECT (demux, "Pushing newseg update %d, rate %g, "
- "applied rate %g, format %d, start %" G_GINT64_FORMAT ", "
- "stop %" G_GINT64_FORMAT, update, rate, arate, GST_FORMAT_TIME,
- start, stop);
- gst_qtdemux_push_event (demux,
- gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,
- start, stop, start));
-
- /* clear leftover in current segment, if any */
- gst_adapter_clear (demux->adapter);
- /* set up streaming thread */
- gst_qtdemux_find_sample (demux, offset, TRUE, TRUE, &stream, &idx, NULL);
- demux->offset = offset;
- if (stream) {
- demux->todrop = stream->samples[idx].offset - offset;
- demux->neededbytes = demux->todrop + stream->samples[idx].size;
- } else {
- /* set up for EOS */
- demux->neededbytes = -1;
- demux->todrop = 0;
- }
- exit:
- gst_event_unref (event);
- res = TRUE;
- goto drop;
- break;
- }
- case GST_EVENT_FLUSH_STOP:
- {
- gint i;
-
- /* clean up, force EOS if no more info follows */
- gst_adapter_clear (demux->adapter);
- demux->offset = 0;
- demux->neededbytes = -1;
- /* reset flow return, e.g. following seek */
- for (i = 0; i < demux->n_streams; i++) {
- demux->streams[i]->last_ret = GST_FLOW_OK;
- demux->streams[i]->sent_eos = FALSE;
- }
- break;
- }
- case GST_EVENT_EOS:
- /* If we are in push mode, and get an EOS before we've seen any streams,
- * then error out - we have nowhere to send the EOS */
- if (!demux->pullbased && demux->n_streams == 0) {
- GST_ELEMENT_ERROR (demux, STREAM, DECODE,
- (_("This file contains no playable streams.")),
- ("no known streams found"));
- }
- break;
- default:
- break;
- }
-
- res = gst_pad_event_default (demux->sinkpad, event);
-
-drop:
- return res;
-}
-
-static GstStateChangeReturn
-gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
-{
- GstQTDemux *qtdemux = GST_QTDEMUX (element);
- GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- break;
- default:
- break;
- }
-
- result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:{
- gint n;
-
- qtdemux->state = QTDEMUX_STATE_INITIAL;
- qtdemux->last_ts = GST_CLOCK_TIME_NONE;
- qtdemux->neededbytes = 16;
- qtdemux->todrop = 0;
- qtdemux->pullbased = FALSE;
- qtdemux->offset = 0;
- qtdemux->mdatoffset = GST_CLOCK_TIME_NONE;
- if (qtdemux->mdatbuffer)
- gst_buffer_unref (qtdemux->mdatbuffer);
- qtdemux->mdatbuffer = NULL;
- gst_adapter_clear (qtdemux->adapter);
- for (n = 0; n < qtdemux->n_streams; n++) {
- QtDemuxStream *stream = qtdemux->streams[n];
-
- while (stream->buffers) {
- gst_buffer_unref (GST_BUFFER_CAST (stream->buffers->data));
- stream->buffers =
- g_slist_delete_link (stream->buffers, stream->buffers);
- }
- if (stream->pad)
- gst_element_remove_pad (element, stream->pad);
- if (stream->samples)
- g_free (stream->samples);
- if (stream->caps)
- gst_caps_unref (stream->caps);
- if (stream->segments)
- g_free (stream->segments);
- g_free (stream);
- }
- qtdemux->major_brand = 0;
- qtdemux->n_streams = 0;
- qtdemux->n_video_streams = 0;
- qtdemux->n_audio_streams = 0;
- qtdemux->n_subp_streams = 0;
- gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
- break;
- }
- default:
- break;
- }
-
- return result;
-}
-
-static void
-extract_initial_length_and_fourcc (const guint8 * data, guint64 * plength,
- guint32 * pfourcc)
-{
- guint64 length;
- guint32 fourcc;
-
- length = QT_UINT32 (data);
- GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length);
- fourcc = QT_FOURCC (data + 4);
- GST_DEBUG ("atom type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
-
- if (length == 0) {
- length = G_MAXUINT32;
- } else if (length == 1) {
- /* this means we have an extended size, which is the 64 bit value of
- * the next 8 bytes */
- length = QT_UINT64 (data + 8);
- GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length);
- }
-
- if (plength)
- *plength = length;
- if (pfourcc)
- *pfourcc = fourcc;
-}
-
-static GstFlowReturn
-gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
-{
- guint64 length = 0;
- guint32 fourcc;
- GstBuffer *buf = NULL;
- GstFlowReturn ret = GST_FLOW_OK;
- guint64 cur_offset = qtdemux->offset;
-
- ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, 16, &buf);
- if (G_UNLIKELY (ret != GST_FLOW_OK))
- goto beach;
- if (G_LIKELY (GST_BUFFER_SIZE (buf) == 16))
- extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), &length, &fourcc);
- gst_buffer_unref (buf);
-
- if (G_UNLIKELY (length == 0)) {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file is invalid and cannot be played.")),
- ("Header atom '%" GST_FOURCC_FORMAT "' has empty length",
- GST_FOURCC_ARGS (fourcc)));
- ret = GST_FLOW_ERROR;
- goto beach;
- }
-
- switch (fourcc) {
- case FOURCC_mdat:
- case FOURCC_free:
- case FOURCC_wide:
- case FOURCC_PICT:
- case FOURCC_pnot:
- {
- GST_LOG_OBJECT (qtdemux,
- "skipping atom '%" GST_FOURCC_FORMAT "' at %" G_GUINT64_FORMAT,
- GST_FOURCC_ARGS (fourcc), cur_offset);
- qtdemux->offset += length;
- break;
- }
- case FOURCC_moov:
- {
- GstBuffer *moov;
-
- ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &moov);
- if (ret != GST_FLOW_OK)
- goto beach;
- if (length != GST_BUFFER_SIZE (moov)) {
- /* Some files have a 'moov' atom at the end of the file which contains
- * a terminal 'free' atom where the body of the atom is missing.
- * Check for, and permit, this special case.
- */
- if (GST_BUFFER_SIZE (moov) >= 8) {
- guint8 *final_data = GST_BUFFER_DATA (moov) +
- (GST_BUFFER_SIZE (moov) - 8);
- guint32 final_length = QT_UINT32 (final_data);
- guint32 final_fourcc = QT_FOURCC (final_data + 4);
- if (final_fourcc == FOURCC_free &&
- GST_BUFFER_SIZE (moov) + final_length - 8 == length) {
- /* Ok, we've found that special case. Allocate a new buffer with
- * that free atom actually present. */
- GstBuffer *newmoov = gst_buffer_new_and_alloc (length);
- gst_buffer_copy_metadata (newmoov, moov,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
- GST_BUFFER_COPY_CAPS);
- memcpy (GST_BUFFER_DATA (newmoov), GST_BUFFER_DATA (moov),
- GST_BUFFER_SIZE (moov));
- memset (GST_BUFFER_DATA (newmoov) + GST_BUFFER_SIZE (moov), 0,
- final_length - 8);
- gst_buffer_unref (moov);
- moov = newmoov;
- }
- }
- }
-
- if (length != GST_BUFFER_SIZE (moov)) {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file is incomplete and cannot be played.")),
- ("We got less than expected (received %u, wanted %u, offset %"
- G_GUINT64_FORMAT ")",
- GST_BUFFER_SIZE (moov), (guint) length, cur_offset));
- ret = GST_FLOW_ERROR;
- goto beach;
- }
- qtdemux->offset += length;
-
- qtdemux_parse_moov (qtdemux, GST_BUFFER_DATA (moov), length);
- qtdemux_node_dump (qtdemux, qtdemux->moov_node);
-
- qtdemux_parse_tree (qtdemux);
- g_node_destroy (qtdemux->moov_node);
- gst_buffer_unref (moov);
- qtdemux->moov_node = NULL;
- qtdemux->state = QTDEMUX_STATE_MOVIE;
- GST_DEBUG_OBJECT (qtdemux, "switching state to STATE_MOVIE (%d)",
- qtdemux->state);
- break;
- }
- case FOURCC_ftyp:
- {
- GstBuffer *ftyp;
-
- /* extract major brand; might come in handy for ISO vs QT issues */
- ret = gst_qtdemux_pull_atom (qtdemux, cur_offset, length, &ftyp);
- if (ret != GST_FLOW_OK)
- goto beach;
- qtdemux->offset += length;
- /* only consider at least a sufficiently complete ftyp atom */
- if (length >= 20) {
- qtdemux->major_brand = QT_FOURCC (GST_BUFFER_DATA (ftyp) + 8);
- GST_DEBUG_OBJECT (qtdemux, "major brand: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (qtdemux->major_brand));
- }
- gst_buffer_unref (ftyp);
- break;
- }
- default:
- {
- GstBuffer *unknown;
-
- GST_LOG_OBJECT (qtdemux,
- "unknown %08x '%" GST_FOURCC_FORMAT "' of size %" G_GUINT64_FORMAT
- " at %" G_GUINT64_FORMAT, fourcc, GST_FOURCC_ARGS (fourcc), length,
- cur_offset);
- ret = gst_qtdemux_pull_atom (qtdemux, cur_offset, length, &unknown);
- if (ret != GST_FLOW_OK)
- goto beach;
- GST_MEMDUMP ("Unknown tag", GST_BUFFER_DATA (unknown),
- GST_BUFFER_SIZE (unknown));
- gst_buffer_unref (unknown);
- qtdemux->offset += length;
- break;
- }
- }
-
-beach:
- return ret;
-}
-
-/* Seeks to the previous keyframe of the indexed stream and
- * aligns other streams with respect to the keyframe timestamp
- * of indexed stream. Only called in case of Reverse Playback
- */
-static GstFlowReturn
-gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
-{
- guint8 n = 0;
- guint32 seg_idx = 0, k_index = 0;
- guint64 k_pos = 0, last_stop = 0;
- QtDemuxSegment *seg = NULL;
- QtDemuxStream *ref_str = NULL;
-
- /* Now we choose an arbitrary stream, get the previous keyframe timestamp
- * and finally align all the other streams on that timestamp with their
- * respective keyframes */
- for (n = 0; n < qtdemux->n_streams; n++) {
- QtDemuxStream *str = qtdemux->streams[n];
-
- seg_idx = gst_qtdemux_find_segment (qtdemux, str,
- qtdemux->segment.last_stop);
-
- /* segment not found, continue with normal flow */
- if (seg_idx == -1)
- continue;
-
- /* No candidate yet, take that one */
- if (!ref_str) {
- ref_str = str;
- continue;
- }
-
- /* So that stream has a segment, we prefer video streams */
- if (str->subtype == FOURCC_vide) {
- ref_str = str;
- break;
- }
- }
-
- if (G_UNLIKELY (!ref_str)) {
- GST_DEBUG_OBJECT (qtdemux, "couldn't find any stream");
- goto eos;
- }
-
- if (G_UNLIKELY (!ref_str->from_sample)) {
- GST_DEBUG_OBJECT (qtdemux, "reached the beginning of the file");
- goto eos;
- }
-
- /* So that stream has been playing from from_sample to to_sample. We will
- * get the timestamp of the previous sample and search for a keyframe before
- * that. For audio streams we do an arbitrary jump in the past (10 samples) */
- if (ref_str->subtype == FOURCC_vide) {
- k_index = gst_qtdemux_find_keyframe (qtdemux, ref_str,
- ref_str->from_sample - 1);
- } else {
- k_index = ref_str->from_sample - 10;
- }
-
- /* get current segment for that stream */
- seg = &ref_str->segments[ref_str->segment_index];
- /* Crawl back through segments to find the one containing this I frame */
- while (ref_str->samples[k_index].timestamp < seg->media_start) {
- GST_DEBUG_OBJECT (qtdemux, "keyframe position is out of segment %u",
- ref_str->segment_index);
- if (G_UNLIKELY (!ref_str->segment_index)) {
- /* Reached first segment, let's consider it's EOS */
- goto eos;
- }
- ref_str->segment_index--;
- seg = &ref_str->segments[ref_str->segment_index];
- }
- /* Calculate time position of the keyframe and where we should stop */
- k_pos = (ref_str->samples[k_index].timestamp - seg->media_start) + seg->time;
- last_stop = ref_str->samples[ref_str->from_sample].timestamp;
- last_stop = (last_stop - seg->media_start) + seg->time;
-
- GST_DEBUG_OBJECT (qtdemux, "preferred stream played from sample %u, "
- "now going to sample %u (pts %" GST_TIME_FORMAT ")", ref_str->from_sample,
- k_index, GST_TIME_ARGS (k_pos));
-
- /* Set last_stop with the keyframe timestamp we pushed of that stream */
- gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, last_stop);
- GST_DEBUG_OBJECT (qtdemux, "last_stop now is %" GST_TIME_FORMAT,
- GST_TIME_ARGS (last_stop));
-
- if (G_UNLIKELY (last_stop < qtdemux->segment.start)) {
- GST_DEBUG_OBJECT (qtdemux, "reached the beginning of segment");
- goto eos;
- }
-
- /* Align them all on this */
- for (n = 0; n < qtdemux->n_streams; n++) {
- guint32 index = 0;
- guint64 media_start = 0, seg_time = 0;
- QtDemuxStream *str = qtdemux->streams[n];
-
- seg_idx = gst_qtdemux_find_segment (qtdemux, str, k_pos);
- GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx);
-
- /* segment not found, continue with normal flow */
- if (seg_idx == -1)
- continue;
-
- /* get segment and time in the segment */
- seg = &str->segments[seg_idx];
- seg_time = k_pos - seg->time;
-
- /* get the media time in the segment */
- media_start = seg->media_start + seg_time;
-
- /* get the index of the sample with media time */
- index = gst_qtdemux_find_index (qtdemux, str, media_start);
- GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
- GST_TIME_ARGS (media_start), index);
-
- /* find previous keyframe */
- k_index = gst_qtdemux_find_keyframe (qtdemux, str, index);
-
- /* Remember until where we want to go */
- str->to_sample = str->from_sample - 1;
- /* Define our time position */
- str->time_position =
- (str->samples[k_index].timestamp - seg->media_start) + seg->time;
- /* Now seek back in time */
- gst_qtdemux_move_stream (qtdemux, str, k_index);
- GST_DEBUG_OBJECT (qtdemux, "keyframe at %u, time position %"
- GST_TIME_FORMAT " playing from sample %u to %u", k_index,
- GST_TIME_ARGS (str->time_position), str->from_sample, str->to_sample);
- }
-
- return GST_FLOW_OK;
-
-eos:
- return GST_FLOW_UNEXPECTED;
-}
-
-/* activate the given segment number @seg_idx of @stream at time @offset.
- * @offset is an absolute global position over all the segments.
- *
- * This will push out a NEWSEGMENT event with the right values and
- * position the stream index to the first decodable sample before
- * @offset.
- */
-static gboolean
-gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
- guint32 seg_idx, guint64 offset)
-{
- GstEvent *event;
- QtDemuxSegment *segment;
- guint32 index, kf_index;
- guint64 seg_time;
- guint64 start, stop, time;
- gdouble rate;
-
- GST_LOG_OBJECT (qtdemux, "activate segment %d, offset %" G_GUINT64_FORMAT,
- seg_idx, offset);
-
- /* update the current segment */
- stream->segment_index = seg_idx;
-
- /* get the segment */
- segment = &stream->segments[seg_idx];
-
- if (G_UNLIKELY (offset < segment->time)) {
- GST_WARNING_OBJECT (qtdemux, "offset < segment->time %" G_GUINT64_FORMAT,
- segment->time);
- return FALSE;
- }
-
- /* get time in this segment */
- seg_time = offset - segment->time;
-
- GST_LOG_OBJECT (qtdemux, "seg_time %" GST_TIME_FORMAT,
- GST_TIME_ARGS (seg_time));
-
- if (G_UNLIKELY (seg_time > segment->duration)) {
- GST_LOG_OBJECT (qtdemux, "seg_time > segment->duration %" GST_TIME_FORMAT,
- GST_TIME_ARGS (segment->duration));
- return FALSE;
- }
-
- /* qtdemux->segment.stop is in outside-time-realm, whereas
- * segment->media_stop is in track-time-realm.
- *
- * In order to compare the two, we need to bring segment.stop
- * into the track-time-realm */
-
- if (qtdemux->segment.stop == -1)
- stop = segment->media_stop;
- else
- stop =
- MIN (segment->media_stop,
- qtdemux->segment.stop - segment->time + segment->media_start);
-
- if (qtdemux->segment.rate >= 0) {
- start = MIN (segment->media_start + seg_time, stop);
- time = offset;
- } else {
- start = segment->media_start;
- stop = MIN (segment->media_start + seg_time, stop);
- time = segment->time;
- }
-
- GST_DEBUG_OBJECT (qtdemux, "newsegment %d from %" GST_TIME_FORMAT
- " to %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, seg_idx,
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time));
-
- /* combine global rate with that of the segment */
- rate = segment->rate * qtdemux->segment.rate;
-
- /* update the segment values used for clipping */
- gst_segment_init (&stream->segment, GST_FORMAT_TIME);
- gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME,
- start, stop, time);
-
- /* now prepare and send the segment */
- if (stream->pad) {
- event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,
- start, stop, time);
- gst_pad_push_event (stream->pad, event);
- /* assume we can send more data now */
- stream->last_ret = GST_FLOW_OK;
- }
-
- /* and move to the keyframe before the indicated media time of the
- * segment */
- if (qtdemux->segment.rate >= 0) {
- index = gst_qtdemux_find_index (qtdemux, stream, start);
- stream->to_sample = stream->n_samples;
- GST_DEBUG_OBJECT (qtdemux, "moving data pointer to %" GST_TIME_FORMAT
- ", index: %u, pts %" GST_TIME_FORMAT, GST_TIME_ARGS (start), index,
- GST_TIME_ARGS (stream->samples[index].timestamp));
- } else {
- index = gst_qtdemux_find_index (qtdemux, stream, stop);
- stream->to_sample = index;
- GST_DEBUG_OBJECT (qtdemux, "moving data pointer to %" GST_TIME_FORMAT
- ", index: %u, pts %" GST_TIME_FORMAT, GST_TIME_ARGS (stop), index,
- GST_TIME_ARGS (stream->samples[index].timestamp));
- }
-
- /* we're at the right spot */
- if (index == stream->sample_index) {
- GST_DEBUG_OBJECT (qtdemux, "we are at the right index");
- return TRUE;
- }
-
- /* find keyframe of the target index */
- kf_index = gst_qtdemux_find_keyframe (qtdemux, stream, index);
-
- /* if we move forwards, we don't have to go back to the previous
- * keyframe since we already sent that. We can also just jump to
- * the keyframe right before the target index if there is one. */
- if (index > stream->sample_index) {
- /* moving forwards check if we move past a keyframe */
- if (kf_index > stream->sample_index) {
- GST_DEBUG_OBJECT (qtdemux, "moving forwards to keyframe at %u (pts %"
- GST_TIME_FORMAT, kf_index,
- GST_TIME_ARGS (stream->samples[kf_index].timestamp));
- gst_qtdemux_move_stream (qtdemux, stream, kf_index);
- } else {
- GST_DEBUG_OBJECT (qtdemux, "moving forwards, keyframe at %u (pts %"
- GST_TIME_FORMAT " already sent", kf_index,
- GST_TIME_ARGS (stream->samples[kf_index].timestamp));
- }
- } else {
- GST_DEBUG_OBJECT (qtdemux, "moving backwards to keyframe at %u (pts %"
- GST_TIME_FORMAT, kf_index,
- GST_TIME_ARGS (stream->samples[kf_index].timestamp));
- gst_qtdemux_move_stream (qtdemux, stream, kf_index);
- }
-
- return TRUE;
-}
-
-/* prepare to get the current sample of @stream, getting essential values.
- *
- * This function will also prepare and send the segment when needed.
- *
- * Return FALSE if the stream is EOS.
- */
-static gboolean
-gst_qtdemux_prepare_current_sample (GstQTDemux * qtdemux,
- QtDemuxStream * stream, guint64 * offset, guint * size, guint64 * timestamp,
- guint64 * duration, gboolean * keyframe)
-{
- QtDemuxSample *sample;
- guint64 time_position;
- guint32 seg_idx;
-
- g_return_val_if_fail (stream != NULL, FALSE);
-
- time_position = stream->time_position;
- if (G_UNLIKELY (time_position == -1))
- goto eos;
-
- seg_idx = stream->segment_index;
- if (G_UNLIKELY (seg_idx == -1)) {
- /* find segment corresponding to time_position if we are looking
- * for a segment. */
- seg_idx = gst_qtdemux_find_segment (qtdemux, stream, time_position);
-
- /* nothing found, we're really eos */
- if (seg_idx == -1)
- goto eos;
- }
-
- /* different segment, activate it, sample_index will be set. */
- if (G_UNLIKELY (stream->segment_index != seg_idx))
- gst_qtdemux_activate_segment (qtdemux, stream, seg_idx, time_position);
-
- GST_LOG_OBJECT (qtdemux, "segment active, index = %u of %u",
- stream->sample_index, stream->n_samples);
-
- /* send out pending buffers */
- while (stream->buffers) {
- GstBuffer *buffer = (GstBuffer *) stream->buffers->data;
-
- if (G_UNLIKELY (stream->discont)) {
- GST_LOG_OBJECT (qtdemux, "marking discont buffer");
- GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
- stream->discont = FALSE;
- }
- gst_buffer_set_caps (buffer, stream->caps);
-
- gst_pad_push (stream->pad, buffer);
-
- stream->buffers = g_slist_delete_link (stream->buffers, stream->buffers);
- }
-
- if (G_UNLIKELY (stream->sample_index >= stream->n_samples))
- goto eos;
-
- /* now get the info for the sample we're at */
- sample = &stream->samples[stream->sample_index];
-
- *timestamp = sample->timestamp + sample->pts_offset;
- *offset = sample->offset;
- *size = sample->size;
- *duration = sample->duration;
- *keyframe = stream->all_keyframe || sample->keyframe;
-
- /* add padding */
- if (stream->padding) {
- *offset += stream->padding;
- *size -= stream->padding;
- }
-
- return TRUE;
-
- /* special cases */
-eos:
- {
- stream->time_position = -1;
- return FALSE;
- }
-}
-
-/* move to the next sample in @stream.
- *
- * Moves to the next segment when needed.
- */
-static void
-gst_qtdemux_advance_sample (GstQTDemux * qtdemux, QtDemuxStream * stream)
-{
- QtDemuxSample *sample;
- QtDemuxSegment *segment;
-
- if (G_UNLIKELY (stream->sample_index >= stream->to_sample)) {
- /* Mark the stream as EOS */
- GST_DEBUG_OBJECT (qtdemux, "reached max allowed sample %u, mark EOS",
- stream->to_sample);
- stream->time_position = -1;
- return;
- }
-
- /* move to next sample */
- stream->sample_index++;
-
- /* get current segment */
- segment = &stream->segments[stream->segment_index];
-
- /* reached the last sample, we need the next segment */
- if (G_UNLIKELY (stream->sample_index >= stream->n_samples))
- goto next_segment;
-
- /* get next sample */
- sample = &stream->samples[stream->sample_index];
-
- /* see if we are past the segment */
- if (G_UNLIKELY (sample->timestamp >= segment->media_stop))
- goto next_segment;
-
- if (sample->timestamp >= segment->media_start) {
- /* inside the segment, update time_position, looks very familiar to
- * GStreamer segments, doesn't it? */
- stream->time_position =
- (sample->timestamp - segment->media_start) + segment->time;
- } else {
- /* not yet in segment, time does not yet increment. This means
- * that we are still prerolling keyframes to the decoder so it can
- * decode the first sample of the segment. */
- stream->time_position = segment->time;
- }
- return;
-
- /* move to the next segment */
-next_segment:
- {
- GST_DEBUG_OBJECT (qtdemux, "segment %d ended ", stream->segment_index);
-
- if (stream->segment_index == stream->n_segments - 1) {
- /* are we at the end of the last segment, we're EOS */
- stream->time_position = -1;
- } else {
- /* else we're only at the end of the current segment */
- stream->time_position = segment->stop_time;
- }
- /* make sure we select a new segment */
- stream->segment_index = -1;
- }
-}
-
-static void
-gst_qtdemux_sync_streams (GstQTDemux * demux)
-{
- gint i;
-
- if (demux->n_streams <= 1)
- return;
-
- for (i = 0; i < demux->n_streams; i++) {
- QtDemuxStream *stream;
- GstClockTime end_time;
-
- stream = demux->streams[i];
-
- if (!stream->pad)
- continue;
-
- /* TODO advance time on subtitle streams here, if any some day */
-
- /* some clips/trailers may have unbalanced streams at the end,
- * so send EOS on shorter stream to prevent stalling others */
-
- /* do not mess with EOS if SEGMENT seeking */
- if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT)
- continue;
-
- if (demux->pullbased) {
- /* loop mode is sample time based */
- if (stream->time_position != -1)
- continue;
- } else {
- /* push mode is byte position based */
- if (stream->samples[stream->n_samples - 1].offset >= demux->offset)
- continue;
- }
-
- if (stream->sent_eos)
- continue;
-
- /* only act if some gap */
- end_time = stream->segments[stream->n_segments - 1].stop_time;
- GST_LOG_OBJECT (demux, "current position: %" GST_TIME_FORMAT
- ", stream end: %" GST_TIME_FORMAT, GST_TIME_ARGS (end_time),
- GST_TIME_ARGS (demux->segment.last_stop));
- if (end_time + 2 * GST_SECOND < demux->segment.last_stop) {
- GST_DEBUG_OBJECT (demux, "sending EOS for stream %s",
- GST_PAD_NAME (stream->pad));
- stream->sent_eos = TRUE;
- gst_pad_push_event (stream->pad, gst_event_new_eos ());
- }
- }
-}
-
-/* UNEXPECTED and NOT_LINKED need to be combined. This means that we return:
- *
- * GST_FLOW_NOT_LINKED: when all pads NOT_LINKED.
- * GST_FLOW_UNEXPECTED: when all pads UNEXPECTED or NOT_LINKED.
- */
-static GstFlowReturn
-gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream,
- GstFlowReturn ret)
-{
- gint i;
- gboolean unexpected = FALSE, not_linked = TRUE;
-
- GST_LOG_OBJECT (demux, "flow return: %s", gst_flow_get_name (ret));
-
- /* store the value */
- stream->last_ret = ret;
-
- for (i = 0; i < demux->n_streams; i++) {
- QtDemuxStream *ostream = demux->streams[i];
-
- ret = ostream->last_ret;
-
- /* no unexpected or unlinked, return */
- if (G_LIKELY (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_NOT_LINKED))
- goto done;
-
- /* we check to see if we have at least 1 unexpected or all unlinked */
- unexpected |= (ret == GST_FLOW_UNEXPECTED);
- not_linked &= (ret == GST_FLOW_NOT_LINKED);
- }
-
- /* when we get here, we all have unlinked or unexpected */
- if (not_linked)
- ret = GST_FLOW_NOT_LINKED;
- else if (unexpected)
- ret = GST_FLOW_UNEXPECTED;
-done:
- GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
- return ret;
-}
-
-/* the input buffer metadata must be writable. Returns NULL when the buffer is
- * completely cliped */
-static GstBuffer *
-gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
- GstBuffer * buf)
-{
- gint64 start, stop, cstart, cstop, diff;
- GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
- guint8 *data;
- guint size;
- gint num_rate, denom_rate;
- gint frame_size;
- gboolean clip_data;
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- /* depending on the type, setup the clip parameters */
- if (stream->subtype == FOURCC_soun) {
- frame_size = stream->bytes_per_frame;
- num_rate = GST_SECOND;
- denom_rate = (gint) stream->rate;
- clip_data = TRUE;
- } else if (stream->subtype == FOURCC_vide) {
- frame_size = size;
- num_rate = stream->fps_n;
- denom_rate = stream->fps_d;
- clip_data = FALSE;
- } else
- goto wrong_type;
-
- /* we can only clip if we have a valid timestamp */
- timestamp = GST_BUFFER_TIMESTAMP (buf);
- if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp)))
- goto no_timestamp;
-
- if (G_LIKELY (GST_BUFFER_DURATION_IS_VALID (buf))) {
- duration = GST_BUFFER_DURATION (buf);
- } else {
- duration =
- gst_util_uint64_scale_int (size / frame_size, num_rate, denom_rate);
- }
-
- start = timestamp;
- stop = start + duration;
-
- if (G_UNLIKELY (!gst_segment_clip (&stream->segment, GST_FORMAT_TIME,
- start, stop, &cstart, &cstop)))
- goto clipped;
-
- /* see if some clipping happened */
- diff = cstart - start;
- if (diff > 0) {
- timestamp = cstart;
- duration -= diff;
-
- if (clip_data) {
- /* bring clipped time to samples and to bytes */
- diff = gst_util_uint64_scale_int (diff, denom_rate, num_rate);
- diff *= frame_size;
-
- GST_DEBUG_OBJECT (qtdemux, "clipping start to %" GST_TIME_FORMAT " %"
- G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff);
-
- data += diff;
- size -= diff;
- }
- }
- diff = stop - cstop;
- if (diff > 0) {
- duration -= diff;
-
- if (clip_data) {
- /* bring clipped time to samples and then to bytes */
- diff = gst_util_uint64_scale_int (diff, denom_rate, num_rate);
- diff *= frame_size;
-
- GST_DEBUG_OBJECT (qtdemux, "clipping stop to %" GST_TIME_FORMAT " %"
- G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
-
- size -= diff;
- }
- }
-
- GST_BUFFER_TIMESTAMP (buf) = timestamp;
- GST_BUFFER_DURATION (buf) = duration;
- GST_BUFFER_SIZE (buf) = size;
- GST_BUFFER_DATA (buf) = data;
-
- return buf;
-
- /* dropped buffer */
-wrong_type:
- {
- GST_DEBUG_OBJECT (qtdemux, "unknown stream type");
- return buf;
- }
-no_timestamp:
- {
- GST_DEBUG_OBJECT (qtdemux, "no timestamp on buffer");
- return buf;
- }
-clipped:
- {
- GST_DEBUG_OBJECT (qtdemux, "clipped buffer");
- gst_buffer_unref (buf);
- return NULL;
- }
-}
-
-static GstFlowReturn
-gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- GstBuffer *buf = NULL;
- QtDemuxStream *stream;
- guint64 min_time;
- guint64 offset = 0;
- guint64 timestamp = GST_CLOCK_TIME_NONE;
- guint64 duration = 0;
- gboolean keyframe = FALSE;
- guint size = 0;
- gint index;
- gint i;
-
- gst_qtdemux_push_pending_newsegment (qtdemux);
-
- /* Figure out the next stream sample to output, min_time is expressed in
- * global time and runs over the edit list segments. */
- min_time = G_MAXUINT64;
- index = -1;
- for (i = 0; i < qtdemux->n_streams; i++) {
- guint64 position;
-
- stream = qtdemux->streams[i];
- position = stream->time_position;
-
- /* position of -1 is EOS */
- if (position != -1 && position < min_time) {
- min_time = position;
- index = i;
- }
- }
- /* all are EOS */
- if (G_UNLIKELY (index == -1)) {
- GST_DEBUG_OBJECT (qtdemux, "all streams are EOS");
- goto eos;
- }
-
- /* check for segment end */
- if (G_UNLIKELY (qtdemux->segment.stop != -1
- && qtdemux->segment.stop < min_time)) {
- GST_DEBUG_OBJECT (qtdemux, "we reached the end of our segment.");
- goto eos;
- }
-
- stream = qtdemux->streams[index];
-
- /* fetch info for the current sample of this stream */
- if (G_UNLIKELY (!gst_qtdemux_prepare_current_sample (qtdemux, stream, &offset,
- &size, ×tamp, &duration, &keyframe)))
- goto eos_stream;
-
- GST_LOG_OBJECT (qtdemux,
- "pushing from stream %d, offset %" G_GUINT64_FORMAT
- ", size %d, timestamp=%" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
- index, offset, size, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
-
- /* hmm, empty sample, skip and move to next sample */
- if (G_UNLIKELY (size <= 0))
- goto next;
-
- /* last pushed sample was out of boundary, goto next sample */
- if (G_UNLIKELY (stream->last_ret == GST_FLOW_UNEXPECTED))
- goto next;
-
- GST_LOG_OBJECT (qtdemux, "reading %d bytes @ %" G_GUINT64_FORMAT, size,
- offset);
-
- ret = gst_qtdemux_pull_atom (qtdemux, offset, size, &buf);
- if (G_UNLIKELY (ret != GST_FLOW_OK))
- goto beach;
-
- if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) {
- GstMessage *m;
- gchar *url;
-
- url = g_strndup ((gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
-
- /* we have RTSP redirect now */
- m = gst_message_new_element (GST_OBJECT_CAST (qtdemux),
- gst_structure_new ("redirect",
- "new-location", G_TYPE_STRING, url, NULL));
- g_free (url);
-
- gst_element_post_message (GST_ELEMENT_CAST (qtdemux), m);
- }
-
- qtdemux->last_ts = min_time;
- if (qtdemux->segment.rate >= 0) {
- gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, min_time);
- gst_qtdemux_sync_streams (qtdemux);
- }
- if (G_LIKELY (stream->pad)) {
- /* we're going to modify the metadata */
- buf = gst_buffer_make_metadata_writable (buf);
-
- GST_BUFFER_TIMESTAMP (buf) = timestamp;
- GST_BUFFER_DURATION (buf) = duration;
- GST_BUFFER_OFFSET (buf) = -1;
- GST_BUFFER_OFFSET_END (buf) = -1;
-
- if (stream->need_clip)
- buf = gst_qtdemux_clip_buffer (qtdemux, stream, buf);
-
- if (buf == NULL)
- goto next;
-
- if (stream->discont) {
- GST_LOG_OBJECT (qtdemux, "marking discont buffer");
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
- stream->discont = FALSE;
- }
-
- if (!keyframe)
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
-
- gst_buffer_set_caps (buf, stream->caps);
-
- GST_LOG_OBJECT (qtdemux,
- "Pushing buffer with time %" GST_TIME_FORMAT ", duration %"
- GST_TIME_FORMAT " on pad %s",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_PAD_NAME (stream->pad));
-
- ret = gst_pad_push (stream->pad, buf);
- } else {
- GST_DEBUG_OBJECT (qtdemux, "No output pad for stream, ignoring");
- gst_buffer_unref (buf);
- ret = GST_FLOW_OK;
- }
-
- /* combine flows */
- ret = gst_qtdemux_combine_flows (qtdemux, stream, ret);
- /* ignore unlinked, we will not push on the pad anymore and we will EOS when
- * we have no more data for the pad to push */
- if (ret == GST_FLOW_UNEXPECTED)
- ret = GST_FLOW_OK;
-
-next:
- gst_qtdemux_advance_sample (qtdemux, stream);
-
-beach:
- return ret;
-
- /* special cases */
-eos:
- {
- GST_DEBUG_OBJECT (qtdemux, "No samples left for any streams - EOS");
- ret = GST_FLOW_UNEXPECTED;
- goto beach;
- }
-eos_stream:
- {
- GST_DEBUG_OBJECT (qtdemux, "No samples left for stream");
- /* EOS will be raised if all are EOS */
- ret = GST_FLOW_OK;
- goto beach;
- }
-}
-
-static void
-gst_qtdemux_loop (GstPad * pad)
-{
- GstQTDemux *qtdemux;
- guint64 cur_offset;
- GstFlowReturn ret;
-
- qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
-
- cur_offset = qtdemux->offset;
- GST_LOG_OBJECT (qtdemux, "loop at position %" G_GUINT64_FORMAT ", state %d",
- cur_offset, qtdemux->state);
-
- switch (qtdemux->state) {
- case QTDEMUX_STATE_INITIAL:
- case QTDEMUX_STATE_HEADER:
- ret = gst_qtdemux_loop_state_header (qtdemux);
- break;
- case QTDEMUX_STATE_MOVIE:
- ret = gst_qtdemux_loop_state_movie (qtdemux);
- if (qtdemux->segment.rate < 0 && ret == GST_FLOW_UNEXPECTED) {
- ret = gst_qtdemux_seek_to_previous_keyframe (qtdemux);
- }
- break;
- default:
- /* ouch */
- goto invalid_state;
- }
-
- /* if something went wrong, pause */
- if (ret != GST_FLOW_OK)
- goto pause;
-
-done:
- gst_object_unref (qtdemux);
- return;
-
- /* ERRORS */
-invalid_state:
- {
- GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED,
- (NULL), ("streaming stopped, invalid state"));
- qtdemux->segment_running = FALSE;
- gst_pad_pause_task (pad);
- gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
- goto done;
- }
-pause:
- {
- const gchar *reason = gst_flow_get_name (ret);
-
- GST_LOG_OBJECT (qtdemux, "pausing task, reason %s", reason);
-
- qtdemux->segment_running = FALSE;
- gst_pad_pause_task (pad);
-
- /* fatal errors need special actions */
- if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
- /* check EOS */
- if (ret == GST_FLOW_UNEXPECTED) {
- if (qtdemux->n_streams == 0) {
- /* we have no streams, post an error */
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file contains no playable streams.")),
- ("no known streams found"));
- }
- if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
- gint64 stop;
-
- /* FIXME: I am not sure this is the right fix. If the sinks are
- * supposed to detect the segment is complete and accumulate
- * automatically, it does not seem to work here. Need more work */
- qtdemux->segment_running = TRUE;
-
- if ((stop = qtdemux->segment.stop) == -1)
- stop = qtdemux->segment.duration;
-
- if (qtdemux->segment.rate >= 0) {
- GST_LOG_OBJECT (qtdemux, "Sending segment done, at end of segment");
- gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
- gst_message_new_segment_done (GST_OBJECT_CAST (qtdemux),
- GST_FORMAT_TIME, stop));
- } else {
- /* For Reverse Playback */
- GST_LOG_OBJECT (qtdemux,
- "Sending segment done, at start of segment");
- gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
- gst_message_new_segment_done (GST_OBJECT_CAST (qtdemux),
- GST_FORMAT_TIME, qtdemux->segment.start));
- }
- } else {
- GST_LOG_OBJECT (qtdemux, "Sending EOS at end of segment");
- gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
- }
- } else {
- GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED,
- (NULL), ("streaming stopped, reason %s", reason));
- gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
- }
- }
- goto done;
- }
-}
-
-/*
- * next_entry_size
- *
- * Returns the size of the first entry at the current offset.
- * If -1, there are none (which means EOS or empty file).
- */
-static guint64
-next_entry_size (GstQTDemux * demux)
-{
- QtDemuxStream *stream;
- int i;
- int smallidx = -1;
- guint64 smalloffs = (guint64) - 1;
-
- GST_LOG_OBJECT (demux, "Finding entry at offset %lld", demux->offset);
-
- for (i = 0; i < demux->n_streams; i++) {
- stream = demux->streams[i];
-
- if (stream->sample_index == -1)
- stream->sample_index = 0;
-
- if (stream->sample_index >= stream->n_samples) {
- GST_LOG_OBJECT (demux, "stream %d samples exhausted", i);
- continue;
- }
-
- GST_LOG_OBJECT (demux,
- "Checking Stream %d (sample_index:%d / offset:%lld / size:%d)",
- i, stream->sample_index, stream->samples[stream->sample_index].offset,
- stream->samples[stream->sample_index].size);
-
- if (((smalloffs == -1)
- || (stream->samples[stream->sample_index].offset < smalloffs))
- && (stream->samples[stream->sample_index].size)) {
- smallidx = i;
- smalloffs = stream->samples[stream->sample_index].offset;
- }
- }
-
- GST_LOG_OBJECT (demux, "stream %d offset %lld demux->offset :%lld",
- smallidx, smalloffs, demux->offset);
-
- if (smallidx == -1)
- return -1;
- stream = demux->streams[smallidx];
-
- if (stream->samples[stream->sample_index].offset >= demux->offset) {
- demux->todrop =
- stream->samples[stream->sample_index].offset - demux->offset;
- return stream->samples[stream->sample_index].size + demux->todrop;
- }
-
- GST_DEBUG_OBJECT (demux, "There wasn't any entry at offset %lld",
- demux->offset);
- return -1;
-}
-
-static void
-gst_qtdemux_post_progress (GstQTDemux * demux, gint num, gint denom)
-{
- gint perc = (gint) ((gdouble) num * 100.0 / (gdouble) denom);
-
- gst_element_post_message (GST_ELEMENT_CAST (demux),
- gst_message_new_element (GST_OBJECT_CAST (demux),
- gst_structure_new ("progress", "percent", G_TYPE_INT, perc, NULL)));
-}
-
-/* FIXME, unverified after edit list updates */
-static GstFlowReturn
-gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
-{
- GstQTDemux *demux;
- GstFlowReturn ret = GST_FLOW_OK;
-
- demux = GST_QTDEMUX (gst_pad_get_parent (sinkpad));
-
- gst_adapter_push (demux->adapter, inbuf);
-
- /* we never really mean to buffer that much */
- if (demux->neededbytes == -1)
- goto eos;
-
- GST_DEBUG_OBJECT (demux, "pushing in inbuf %p, neededbytes:%u, available:%u",
- inbuf, demux->neededbytes, gst_adapter_available (demux->adapter));
-
- while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) &&
- (ret == GST_FLOW_OK)) {
-
- GST_DEBUG_OBJECT (demux,
- "state:%d , demux->neededbytes:%d, demux->offset:%lld", demux->state,
- demux->neededbytes, demux->offset);
-
- switch (demux->state) {
- case QTDEMUX_STATE_INITIAL:{
- const guint8 *data;
- guint32 fourcc;
- guint64 size;
-
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);
-
- /* get fourcc/length, set neededbytes */
- extract_initial_length_and_fourcc ((guint8 *) data, &size, &fourcc);
- GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] "
- "size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size);
- if (size == 0) {
- GST_ELEMENT_ERROR (demux, STREAM, DECODE,
- (_("This file is invalid and cannot be played.")),
- ("initial atom '%" GST_FOURCC_FORMAT "' has empty length",
- GST_FOURCC_ARGS (fourcc)));
- ret = GST_FLOW_ERROR;
- break;
- }
- if (fourcc == FOURCC_mdat) {
- if (demux->n_streams > 0) {
- demux->state = QTDEMUX_STATE_MOVIE;
- demux->neededbytes = next_entry_size (demux);
- } else {
- guint bs;
-
- buffer_data:
- /* there may be multiple mdat (or alike) buffers */
- /* sanity check */
- if (demux->mdatbuffer)
- bs = GST_BUFFER_SIZE (demux->mdatbuffer);
- else
- bs = 0;
- if (size + bs > 10 * (1 << 20))
- goto no_moov;
- demux->state = QTDEMUX_STATE_BUFFER_MDAT;
- demux->neededbytes = size;
- if (!demux->mdatbuffer)
- demux->mdatoffset = demux->offset;
- }
- } else if (G_UNLIKELY (size > QTDEMUX_MAX_ATOM_SIZE)) {
- GST_ELEMENT_ERROR (demux, STREAM, DECODE,
- (_("This file is invalid and cannot be played.")),
- ("atom %" GST_FOURCC_FORMAT " has bogus size %" G_GUINT64_FORMAT,
- GST_FOURCC_ARGS (fourcc), size));
- ret = GST_FLOW_ERROR;
- break;
- } else {
- /* this means we already started buffering and still no moov header,
- * let's continue buffering everything till we get moov */
- if (demux->mdatbuffer && (fourcc != FOURCC_moov))
- goto buffer_data;
- demux->neededbytes = size;
- demux->state = QTDEMUX_STATE_HEADER;
- }
- break;
- }
- case QTDEMUX_STATE_HEADER:{
- const guint8 *data;
- guint32 fourcc;
-
- GST_DEBUG_OBJECT (demux, "In header");
-
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);
-
- /* parse the header */
- extract_initial_length_and_fourcc (data, NULL, &fourcc);
- if (fourcc == FOURCC_moov) {
- GST_DEBUG_OBJECT (demux, "Parsing [moov]");
-
- qtdemux_parse_moov (demux, data, demux->neededbytes);
- qtdemux_node_dump (demux, demux->moov_node);
- qtdemux_parse_tree (demux);
-
- g_node_destroy (demux->moov_node);
- demux->moov_node = NULL;
- GST_DEBUG_OBJECT (demux, "Finished parsing the header");
- } else {
- GST_WARNING_OBJECT (demux,
- "Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- /* Let's jump that one and go back to initial state */
- }
-
- if (demux->mdatbuffer && demux->n_streams) {
- GstBuffer *buf;
-
- /* the mdat was before the header */
- GST_DEBUG_OBJECT (demux, "We have n_streams:%d and mdatbuffer:%p",
- demux->n_streams, demux->mdatbuffer);
- /* restore our adapter/offset view of things with upstream;
- * put preceding buffered data ahead of current moov data.
- * This should also handle evil mdat, moov, mdat cases and alike */
- buf = gst_adapter_take_buffer (demux->adapter,
- gst_adapter_available (demux->adapter));
- gst_adapter_clear (demux->adapter);
- gst_adapter_push (demux->adapter, demux->mdatbuffer);
- gst_adapter_push (demux->adapter, buf);
- demux->mdatbuffer = NULL;
- demux->offset = demux->mdatoffset;
- demux->neededbytes = next_entry_size (demux);
- demux->state = QTDEMUX_STATE_MOVIE;
- } else {
- GST_DEBUG_OBJECT (demux, "Carrying on normally");
- gst_adapter_flush (demux->adapter, demux->neededbytes);
- demux->offset += demux->neededbytes;
- demux->neededbytes = 16;
- demux->state = QTDEMUX_STATE_INITIAL;
- }
-
- break;
- }
- case QTDEMUX_STATE_BUFFER_MDAT:{
- GstBuffer *buf;
-
- GST_DEBUG_OBJECT (demux, "Got our buffer at offset %lld",
- demux->offset);
- buf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
- GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (QT_FOURCC (GST_BUFFER_DATA (buf) + 4)));
- if (demux->mdatbuffer)
- demux->mdatbuffer = gst_buffer_join (demux->mdatbuffer, buf);
- else
- demux->mdatbuffer = buf;
- demux->offset += demux->neededbytes;
- demux->neededbytes = 16;
- demux->state = QTDEMUX_STATE_INITIAL;
- gst_qtdemux_post_progress (demux, 1, 1);
-
- break;
- }
- case QTDEMUX_STATE_MOVIE:{
- GstBuffer *outbuf;
- QtDemuxStream *stream = NULL;
- int i = -1;
-
- GST_DEBUG_OBJECT (demux, "BEGIN // in MOVIE for offset %lld",
- demux->offset);
-
- if (demux->todrop) {
- GST_LOG_OBJECT (demux, "Dropping %d bytes", demux->todrop);
- gst_adapter_flush (demux->adapter, demux->todrop);
- demux->neededbytes -= demux->todrop;
- demux->offset += demux->todrop;
- }
-
- /* Figure out which stream this is packet belongs to */
- for (i = 0; i < demux->n_streams; i++) {
- stream = demux->streams[i];
- if (stream->sample_index >= stream->n_samples)
- continue;
- GST_LOG_OBJECT (demux,
- "Checking stream %d (sample_index:%d / offset:%lld / size:%d)",
- i, stream->sample_index,
- stream->samples[stream->sample_index].offset,
- stream->samples[stream->sample_index].size);
-
- if (stream->samples[stream->sample_index].offset == demux->offset)
- break;
- }
-
- if (G_UNLIKELY (stream == NULL || i == demux->n_streams))
- goto unknown_stream;
-
- /* first buffer? */
- /* initial newsegment sent here after having added pads,
- * possible others in sink_event */
- if (G_UNLIKELY (demux->last_ts == GST_CLOCK_TIME_NONE)) {
- gst_qtdemux_push_event (demux,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
- 0, GST_CLOCK_TIME_NONE, 0));
- }
-
- /* Put data in a buffer, set timestamps, caps, ... */
- outbuf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
- GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (stream->fourcc));
-
- g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
-
- if (stream->samples[stream->sample_index].pts_offset) {
- demux->last_ts = stream->samples[stream->sample_index].timestamp;
- GST_BUFFER_TIMESTAMP (outbuf) = demux->last_ts +
- stream->samples[stream->sample_index].pts_offset;
- } else {
- GST_BUFFER_TIMESTAMP (outbuf) =
- stream->samples[stream->sample_index].timestamp;
- demux->last_ts = GST_BUFFER_TIMESTAMP (outbuf);
- }
- GST_BUFFER_DURATION (outbuf) =
- stream->samples[stream->sample_index].duration;
- if (!stream->all_keyframe &&
- !stream->samples[stream->sample_index].keyframe)
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
-
- /* position reporting */
- gst_segment_set_last_stop (&demux->segment, GST_FORMAT_TIME,
- demux->last_ts);
- gst_qtdemux_sync_streams (demux);
-
- /* send buffer */
- if (stream->pad) {
- GST_LOG_OBJECT (demux,
- "Pushing buffer with time %" GST_TIME_FORMAT " on pad %p",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), stream->pad);
- gst_buffer_set_caps (outbuf, stream->caps);
- ret = gst_pad_push (stream->pad, outbuf);
- } else {
- gst_buffer_unref (outbuf);
- ret = GST_FLOW_OK;
- }
-
- /* combine flows */
- ret = gst_qtdemux_combine_flows (demux, stream, ret);
-
- stream->sample_index++;
-
- /* update current offset and figure out size of next buffer */
- GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u",
- demux->offset, demux->neededbytes);
- demux->offset += demux->neededbytes;
- GST_LOG_OBJECT (demux, "offset is now %lld", demux->offset);
-
- if ((demux->neededbytes = next_entry_size (demux)) == -1)
- goto eos;
- break;
- }
- default:
- goto invalid_state;
- }
- }
-
- /* when buffering movie data, at least show user something is happening */
- if (ret == GST_FLOW_OK && demux->state == QTDEMUX_STATE_BUFFER_MDAT &&
- gst_adapter_available (demux->adapter) <= demux->neededbytes) {
- gst_qtdemux_post_progress (demux, gst_adapter_available (demux->adapter),
- demux->neededbytes);
- }
-done:
- gst_object_unref (demux);
-
- return ret;
-
- /* ERRORS */
-unknown_stream:
- {
- GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), ("unknown stream found"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-eos:
- {
- GST_DEBUG_OBJECT (demux, "no next entry, EOS");
- ret = GST_FLOW_UNEXPECTED;
- goto done;
- }
-invalid_state:
- {
- GST_ELEMENT_ERROR (demux, STREAM, FAILED,
- (NULL), ("qtdemuxer invalid state %d", demux->state));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-no_moov:
- {
- GST_ELEMENT_ERROR (demux, STREAM, FAILED,
- (NULL), ("no 'moov' atom withing first 10 MB"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-}
-
-static gboolean
-qtdemux_sink_activate (GstPad * sinkpad)
-{
- if (gst_pad_check_pull_range (sinkpad))
- return gst_pad_activate_pull (sinkpad, TRUE);
- else
- return gst_pad_activate_push (sinkpad, TRUE);
-}
-
-static gboolean
-qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active)
-{
- GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
-
- if (active) {
- demux->pullbased = TRUE;
- demux->segment_running = TRUE;
- return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop,
- sinkpad);
- } else {
- demux->segment_running = FALSE;
- return gst_pad_stop_task (sinkpad);
- }
-}
-
-static gboolean
-qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active)
-{
- GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
-
- demux->pullbased = FALSE;
-
- return TRUE;
-}
-
-#ifdef HAVE_ZLIB
-static void *
-qtdemux_zalloc (void *opaque, unsigned int items, unsigned int size)
-{
- return g_malloc (items * size);
-}
-
-static void
-qtdemux_zfree (void *opaque, void *addr)
-{
- g_free (addr);
-}
-
-static void *
-qtdemux_inflate (void *z_buffer, int z_length, int length)
-{
- guint8 *buffer;
- z_stream *z;
- int ret;
-
- z = g_new0 (z_stream, 1);
- z->zalloc = qtdemux_zalloc;
- z->zfree = qtdemux_zfree;
- z->opaque = NULL;
-
- z->next_in = z_buffer;
- z->avail_in = z_length;
-
- buffer = (guint8 *) g_malloc (length);
- ret = inflateInit (z);
- while (z->avail_in > 0) {
- if (z->avail_out == 0) {
- length += 1024;
- buffer = (guint8 *) g_realloc (buffer, length);
- z->next_out = buffer + z->total_out;
- z->avail_out = 1024;
- }
- ret = inflate (z, Z_SYNC_FLUSH);
- if (ret != Z_OK)
- break;
- }
- if (ret != Z_STREAM_END) {
- g_warning ("inflate() returned %d", ret);
- }
-
- g_free (z);
- return buffer;
-}
-#endif /* HAVE_ZLIB */
-
-static gboolean
-qtdemux_parse_moov (GstQTDemux * qtdemux, const guint8 * buffer, int length)
-{
- GNode *cmov;
-
- qtdemux->moov_node = g_node_new ((guint8 *) buffer);
-
- GST_DEBUG_OBJECT (qtdemux, "parsing 'moov' atom");
- qtdemux_parse_node (qtdemux, qtdemux->moov_node, buffer, length);
-
- cmov = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_cmov);
- if (cmov) {
- guint32 method;
- GNode *dcom;
- GNode *cmvd;
-
- dcom = qtdemux_tree_get_child_by_type (cmov, FOURCC_dcom);
- cmvd = qtdemux_tree_get_child_by_type (cmov, FOURCC_cmvd);
- if (dcom == NULL || cmvd == NULL)
- goto invalid_compression;
-
- method = QT_FOURCC ((guint8 *) dcom->data + 8);
- switch (method) {
-#ifdef HAVE_ZLIB
- case GST_MAKE_FOURCC ('z', 'l', 'i', 'b'):{
- int uncompressed_length;
- int compressed_length;
- guint8 *buf;
-
- uncompressed_length = QT_UINT32 ((guint8 *) cmvd->data + 8);
- compressed_length = QT_UINT32 ((guint8 *) cmvd->data + 4) - 12;
- GST_LOG ("length = %d", uncompressed_length);
-
- buf =
- (guint8 *) qtdemux_inflate ((guint8 *) cmvd->data + 12,
- compressed_length, uncompressed_length);
-
- qtdemux->moov_node_compressed = qtdemux->moov_node;
- qtdemux->moov_node = g_node_new (buf);
-
- qtdemux_parse_node (qtdemux, qtdemux->moov_node, buf,
- uncompressed_length);
- break;
- }
-#endif /* HAVE_ZLIB */
- default:
- GST_WARNING_OBJECT (qtdemux, "unknown or unhandled header compression "
- "type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (method));
- break;
- }
- }
- return TRUE;
-
- /* ERRORS */
-invalid_compression:
- {
- GST_ERROR_OBJECT (qtdemux, "invalid compressed header");
- return FALSE;
- }
-}
-
-static gboolean
-qtdemux_parse_container (GstQTDemux * qtdemux, GNode * node, const guint8 * buf,
- const guint8 * end)
-{
- while (G_UNLIKELY (buf < end)) {
- GNode *child;
- guint32 len;
-
- if (G_UNLIKELY (buf + 4 > end)) {
- GST_LOG_OBJECT (qtdemux, "buffer overrun");
- break;
- }
- len = QT_UINT32 (buf);
- if (G_UNLIKELY (len == 0)) {
- GST_LOG_OBJECT (qtdemux, "empty container");
- break;
- }
- if (G_UNLIKELY (len < 8)) {
- GST_WARNING_OBJECT (qtdemux, "length too short (%d < 8)", len);
- break;
- }
- if (G_UNLIKELY (len > (end - buf))) {
- GST_WARNING_OBJECT (qtdemux, "length too long (%d > %d)", len, end - buf);
- break;
- }
-
- child = g_node_new ((guint8 *) buf);
- g_node_append (node, child);
- qtdemux_parse_node (qtdemux, child, buf, len);
-
- buf += len;
- }
- return TRUE;
-}
-
-static gboolean
-qtdemux_parse_theora_extension (GstQTDemux * qtdemux, QtDemuxStream * stream,
- GNode * xdxt)
-{
- int len = QT_UINT32 (xdxt->data);
- guint8 *buf = xdxt->data;
- guint8 *end = buf + len;
- GstBuffer *buffer;
-
- /* skip size and type */
- buf += 8;
- end -= 8;
-
- while (buf < end) {
- gint size;
- guint32 type;
-
- size = QT_UINT32 (buf);
- type = QT_FOURCC (buf + 4);
-
- GST_LOG_OBJECT (qtdemux, "%p %p", buf, end);
-
- if (buf + size > end || size <= 0)
- break;
-
- buf += 8;
- size -= 8;
-
- GST_WARNING_OBJECT (qtdemux, "have cookie %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (type));
-
- switch (type) {
- case FOURCC_tCtH:
- buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
- stream->buffers = g_slist_append (stream->buffers, buffer);
- GST_LOG_OBJECT (qtdemux, "parsing theora header");
- break;
- case FOURCC_tCt_:
- buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
- stream->buffers = g_slist_append (stream->buffers, buffer);
- GST_LOG_OBJECT (qtdemux, "parsing theora comment");
- break;
- case FOURCC_tCtC:
- buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
- stream->buffers = g_slist_append (stream->buffers, buffer);
- GST_LOG_OBJECT (qtdemux, "parsing theora codebook");
- break;
- default:
- GST_WARNING_OBJECT (qtdemux,
- "unknown theora cookie %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (type));
- break;
- }
- buf += size;
- }
- return TRUE;
-}
-
-static gboolean
-qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer,
- int length)
-{
- guint32 fourcc;
- guint32 node_length;
- const QtNodeType *type;
- const guint8 *end;
-
- GST_LOG_OBJECT (qtdemux, "qtdemux_parse buffer %p length %d", buffer, length);
-
- node_length = QT_UINT32 (buffer);
- fourcc = QT_FOURCC (buffer + 4);
-
- /* ignore empty nodes */
- if (G_UNLIKELY (fourcc == 0 || node_length == 8))
- return TRUE;
-
- type = qtdemux_type_get (fourcc);
-
- end = buffer + length;
-
- GST_LOG_OBJECT (qtdemux,
- "parsing '%" GST_FOURCC_FORMAT "', length=%d, name '%s'",
- GST_FOURCC_ARGS (fourcc), node_length, type->name);
-
- if (type->flags & QT_FLAG_CONTAINER) {
- qtdemux_parse_container (qtdemux, node, buffer + 8, end);
- } else {
- switch (fourcc) {
- case FOURCC_stsd:
- {
- if (node_length < 20) {
- GST_LOG_OBJECT (qtdemux, "skipping small stsd box");
- break;
- }
- GST_DEBUG_OBJECT (qtdemux,
- "parsing stsd (sample table, sample description) atom");
- qtdemux_parse_container (qtdemux, node, buffer + 16, end);
- break;
- }
- case FOURCC_mp4a:
- {
- guint32 version;
- guint32 offset;
-
- if (length < 20) {
- /* small boxes are also inside wave inside the mp4a box */
- GST_LOG_OBJECT (qtdemux, "skipping small mp4a box");
- break;
- }
- version = QT_UINT32 (buffer + 16);
-
- GST_DEBUG_OBJECT (qtdemux, "mp4a version 0x%08x", version);
-
- /* parse any esds descriptors */
- switch (version) {
- case 0x00000000:
- offset = 0x24;
- break;
- case 0x00010000:
- offset = 0x34;
- break;
- case 0x00020000:
- offset = 0x58;
- break;
- default:
- GST_WARNING_OBJECT (qtdemux, "unhandled mp4a version 0x%08x",
- version);
- offset = 0;
- break;
- }
- if (offset)
- qtdemux_parse_container (qtdemux, node, buffer + offset, end);
- break;
- }
- case FOURCC_mp4v:
- {
- const guint8 *buf;
- guint32 version;
- int tlen;
-
- GST_DEBUG_OBJECT (qtdemux, "parsing in mp4v");
- version = QT_UINT32 (buffer + 16);
- GST_DEBUG_OBJECT (qtdemux, "version %08x", version);
- if (1 || version == 0x00000000) {
- buf = buffer + 0x32;
-
- /* FIXME Quicktime uses PASCAL string while
- * the iso format uses C strings. Check the file
- * type before attempting to parse the string here. */
- tlen = QT_UINT8 (buf);
- GST_DEBUG_OBJECT (qtdemux, "tlen = %d", tlen);
- buf++;
- GST_DEBUG_OBJECT (qtdemux, "string = %.*s", tlen, (char *) buf);
- /* the string has a reserved space of 32 bytes so skip
- * the remaining 31 */
- buf += 31;
- buf += 4; /* and 4 bytes reserved */
-
- GST_MEMDUMP_OBJECT (qtdemux, "mp4v", buf, end - buf);
-
- qtdemux_parse_container (qtdemux, node, buf, end);
- }
- break;
- }
- case FOURCC_mjp2:
- {
- qtdemux_parse_container (qtdemux, node, buffer + 86, end);
- break;
- }
- case FOURCC_meta:
- {
- GST_DEBUG_OBJECT (qtdemux, "parsing meta atom");
- qtdemux_parse_container (qtdemux, node, buffer + 12, end);
- break;
- }
- case FOURCC_XiTh:
- {
- guint32 version;
- guint32 offset;
-
- version = QT_UINT32 (buffer + 12);
- GST_DEBUG_OBJECT (qtdemux, "parsing XiTh atom version 0x%08x", version);
-
- switch (version) {
- case 0x00000001:
- offset = 0x62;
- break;
- default:
- GST_DEBUG_OBJECT (qtdemux, "unknown version 0x%08x", version);
- offset = 0;
- break;
- }
- if (offset)
- qtdemux_parse_container (qtdemux, node, buffer + offset, end);
- break;
- }
- case FOURCC_in24:
- {
- qtdemux_parse_container (qtdemux, node, buffer + 0x34, end);
- break;
- }
- default:
- if (!strcmp (type->name, "unknown"))
- GST_MEMDUMP ("Unknown tag", buffer + 4, end - buffer - 4);
- break;
- }
- }
- GST_LOG_OBJECT (qtdemux, "parsed '%" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- return TRUE;
-}
-
-static GNode *
-qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc)
-{
- GNode *child;
- guint8 *buffer;
- guint32 child_fourcc;
-
- for (child = g_node_first_child (node); child;
- child = g_node_next_sibling (child)) {
- buffer = (guint8 *) child->data;
-
- child_fourcc = QT_FOURCC (buffer + 4);
-
- if (G_UNLIKELY (child_fourcc == fourcc)) {
- return child;
- }
- }
- return NULL;
-}
-
-static GNode *
-qtdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc)
-{
- GNode *child;
- guint8 *buffer;
- guint32 child_fourcc;
-
- for (child = g_node_next_sibling (node); child;
- child = g_node_next_sibling (child)) {
- buffer = (guint8 *) child->data;
-
- child_fourcc = QT_FOURCC (buffer + 4);
-
- if (child_fourcc == fourcc) {
- return child;
- }
- }
- return NULL;
-}
-
-static gboolean
-gst_qtdemux_add_stream (GstQTDemux * qtdemux,
- QtDemuxStream * stream, GstTagList * list)
-{
- if (qtdemux->n_streams >= GST_QTDEMUX_MAX_STREAMS)
- goto too_many_streams;
-
- if (stream->subtype == FOURCC_vide) {
- gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams);
-
- stream->pad =
- gst_pad_new_from_static_template (&gst_qtdemux_videosrc_template, name);
- g_free (name);
-
- /* fps is calculated base on the duration of the first frames since
- * qt does not have a fixed framerate. */
- if ((stream->n_samples == 1) && (stream->min_duration == 0)) {
- /* still frame */
- stream->fps_n = 0;
- stream->fps_d = 1;
- } else {
- stream->fps_n = stream->timescale;
- if (stream->min_duration == 0)
- stream->fps_d = 1;
- else
- stream->fps_d = stream->min_duration;
- }
-
- if (stream->caps) {
- gboolean gray;
- gint depth, palette_count;
- const guint32 *palette_data = NULL;
-
- gst_caps_set_simple (stream->caps,
- "width", G_TYPE_INT, stream->width,
- "height", G_TYPE_INT, stream->height,
- "framerate", GST_TYPE_FRACTION, stream->fps_n, stream->fps_d, NULL);
-
- /* iso files:
- * calculate pixel-aspect-ratio using display width and height */
- if (qtdemux->major_brand != FOURCC_qt__) {
- GST_DEBUG_OBJECT (qtdemux,
- "video size %dx%d, target display size %dx%d", stream->width,
- stream->height, stream->display_width, stream->display_height);
-
- if (stream->display_width > 0 && stream->display_height > 0 &&
- stream->width > 0 && stream->height > 0) {
- gint n, d;
-
- /* calculate the pixel aspect ratio using the display and pixel w/h */
- n = stream->display_width * stream->height;
- d = stream->display_height * stream->width;
- if (n != d) {
- GST_DEBUG_OBJECT (qtdemux, "setting PAR to %d/%d", n, d);
- gst_caps_set_simple (stream->caps, "pixel-aspect-ratio",
- GST_TYPE_FRACTION, n, d, NULL);
- }
- }
- }
-
- /* qt file might have pasp atom */
- if (stream->par_w > 0 && stream->par_h > 0) {
- GST_DEBUG_OBJECT (qtdemux, "par %d:%d", stream->par_w, stream->par_h);
- gst_caps_set_simple (stream->caps, "pixel-aspect-ratio",
- GST_TYPE_FRACTION, stream->par_w, stream->par_h, NULL);
- }
-
- depth = stream->bits_per_sample;
-
- /* more than 32 bits means grayscale */
- gray = (depth > 32);
- /* low 32 bits specify the depth */
- depth &= 0x1F;
-
- /* different number of palette entries is determined by depth. */
- palette_count = 0;
- if ((depth == 1) || (depth == 2) || (depth == 4) || (depth == 8))
- palette_count = (1 << depth);
-
- switch (palette_count) {
- case 0:
- break;
- case 2:
- palette_data = ff_qt_default_palette_2;
- break;
- case 4:
- palette_data = ff_qt_default_palette_4;
- break;
- case 16:
- if (gray)
- palette_data = ff_qt_grayscale_palette_16;
- else
- palette_data = ff_qt_default_palette_16;
- break;
- case 256:
- if (gray)
- palette_data = ff_qt_grayscale_palette_256;
- else
- palette_data = ff_qt_default_palette_256;
- break;
- default:
- GST_ELEMENT_WARNING (qtdemux, STREAM, DECODE,
- (_("The video in this file might not play correctly.")),
- ("unsupported palette depth %d", depth));
- break;
- }
- if (palette_data) {
- GstBuffer *palette;
-
- /* make sure it's not writable. We leave MALLOCDATA to NULL so that we
- * don't free any of the buffer data. */
- palette = gst_buffer_new ();
- GST_BUFFER_FLAG_SET (palette, GST_BUFFER_FLAG_READONLY);
- GST_BUFFER_DATA (palette) = (guint8 *) palette_data;
- GST_BUFFER_SIZE (palette) = sizeof (guint32) * palette_count;
-
- gst_caps_set_simple (stream->caps, "palette_data",
- GST_TYPE_BUFFER, palette, NULL);
- gst_buffer_unref (palette);
- } else if (palette_count != 0) {
- GST_ELEMENT_WARNING (qtdemux, STREAM, NOT_IMPLEMENTED,
- (NULL), ("Unsupported palette depth %d. Ignoring stream.", depth));
-
- gst_object_unref (stream->pad);
- stream->pad = NULL;
- }
- }
- qtdemux->n_video_streams++;
- } else if (stream->subtype == FOURCC_soun) {
- gchar *name = g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams);
-
- stream->pad =
- gst_pad_new_from_static_template (&gst_qtdemux_audiosrc_template, name);
- g_free (name);
- if (stream->caps) {
- gst_caps_set_simple (stream->caps,
- "rate", G_TYPE_INT, (int) stream->rate,
- "channels", G_TYPE_INT, stream->n_channels, NULL);
- }
- qtdemux->n_audio_streams++;
- } else if (stream->subtype == FOURCC_strm) {
- GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad");
- } else if (stream->subtype == FOURCC_subp) {
- gchar *name = g_strdup_printf ("subp_%02d", qtdemux->n_subp_streams);
-
- stream->pad =
- gst_pad_new_from_static_template (&gst_qtdemux_subpsrc_template, name);
- g_free (name);
- qtdemux->n_subp_streams++;
- } else {
- GST_DEBUG_OBJECT (qtdemux, "unknown stream type");
- goto done;
- }
-
- qtdemux->streams[qtdemux->n_streams] = stream;
- qtdemux->n_streams++;
- GST_DEBUG_OBJECT (qtdemux, "n_streams is now %d", qtdemux->n_streams);
-
- if (stream->pad) {
- GST_PAD_ELEMENT_PRIVATE (stream->pad) = stream;
-
- gst_pad_use_fixed_caps (stream->pad);
- gst_pad_set_event_function (stream->pad, gst_qtdemux_handle_src_event);
- gst_pad_set_query_type_function (stream->pad,
- gst_qtdemux_get_src_query_types);
- gst_pad_set_query_function (stream->pad, gst_qtdemux_handle_src_query);
-
- GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps);
- gst_pad_set_caps (stream->pad, stream->caps);
-
- GST_DEBUG_OBJECT (qtdemux, "adding pad %s %p to qtdemux %p",
- GST_OBJECT_NAME (stream->pad), stream->pad, qtdemux);
- gst_pad_set_active (stream->pad, TRUE);
- gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), stream->pad);
- if (list)
- gst_element_found_tags_for_pad (GST_ELEMENT_CAST (qtdemux), stream->pad,
- list);
- }
-done:
- return TRUE;
-
-too_many_streams:
- {
- GST_ELEMENT_WARNING (qtdemux, STREAM, DECODE,
- (_("This file contains too many streams. Only playing first %d"),
- GST_QTDEMUX_MAX_STREAMS), (NULL));
- return TRUE;
- }
-}
-
-/* collect all samples for @stream by reading the info from @stbl
- */
-static gboolean
-qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
- GNode * stbl)
-{
- GNode *stsc;
- GNode *stsz;
- GNode *stco;
- GNode *co64;
- GNode *stts;
- GNode *stss;
- GNode *stps;
- GNode *ctts;
- const guint8 *stsc_data, *stsz_data, *stco_data, *co64_data, *stts_data;
- int sample_size;
- int sample_index;
- int n_samples;
- int n_samples_per_chunk;
- int n_sample_times;
- QtDemuxSample *samples;
- gint i, j, k;
- int index;
- guint64 timestamp, time;
-
- /* sample to chunk */
- if (!(stsc = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsc)))
- goto corrupt_file;
- stsc_data = (const guint8 *) stsc->data;
-
- /* sample size */
- if (!(stsz = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsz)))
- goto corrupt_file;
- stsz_data = (const guint8 *) stsz->data;
-
- /* chunk offsets */
- stco = qtdemux_tree_get_child_by_type (stbl, FOURCC_stco);
- co64 = qtdemux_tree_get_child_by_type (stbl, FOURCC_co64);
- if (stco) {
- stco_data = (const guint8 *) stco->data;
- co64_data = NULL;
- } else {
- stco_data = NULL;
- if (co64 == NULL)
- goto corrupt_file;
- co64_data = (const guint8 *) co64->data;
- }
- /* sample time */
- if (!(stts = qtdemux_tree_get_child_by_type (stbl, FOURCC_stts)))
- goto corrupt_file;
- stts_data = (const guint8 *) stts->data;
-
- sample_size = QT_UINT32 (stsz_data + 12);
- if (sample_size == 0 || stream->sampled) {
- n_samples = QT_UINT32 (stsz_data + 16);
-
- if (n_samples == 0)
- goto no_samples;
- else if (n_samples < 0)
- goto corrupt_file;
-
- GST_DEBUG_OBJECT (qtdemux, "stsz sample_size 0, allocating n_samples %d",
- n_samples);
-
- samples = g_try_new0 (QtDemuxSample, n_samples);
- if (samples == NULL)
- goto out_of_memory;
-
- stream->n_samples = n_samples;
- stream->samples = samples;
-
- /* set the sample sizes */
- if (sample_size == 0) {
- const guint8 *stsz_p = stsz_data + 20;
- /* different sizes for each sample */
- for (i = 0; i < n_samples; i++) {
- samples[i].size = QT_UINT32 (stsz_p);
- GST_LOG_OBJECT (qtdemux, "sample %d has size %d", i, samples[i].size);
- stsz_p += 4;
- }
- } else {
- /* samples have the same size */
- GST_LOG_OBJECT (qtdemux, "all samples have size %d", sample_size);
- for (i = 0; i < n_samples; i++)
- samples[i].size = sample_size;
- }
-
- /* set the sample offsets in the file */
- n_samples_per_chunk = QT_UINT32 (stsc_data + 12);
- index = 0;
- for (i = 0; i < n_samples_per_chunk; i++) {
- guint32 first_chunk, last_chunk;
- guint32 samples_per_chunk;
-
- first_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 0) - 1;
- if (G_UNLIKELY (i == n_samples_per_chunk - 1)) {
- last_chunk = G_MAXUINT32;
- } else {
- last_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 12) - 1;
- }
- samples_per_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 4);
-
- for (j = first_chunk; j < last_chunk; j++) {
- guint64 chunk_offset;
-
- if (stco) {
- chunk_offset = QT_UINT32 (stco_data + 16 + j * 4);
- } else {
- chunk_offset = QT_UINT64 (co64_data + 16 + j * 8);
- }
- for (k = 0; k < samples_per_chunk; k++) {
- GST_LOG_OBJECT (qtdemux, "Creating entry %d with offset %lld",
- index, chunk_offset);
- samples[index].offset = chunk_offset;
- chunk_offset += samples[index].size;
- index++;
- if (G_UNLIKELY (index >= n_samples))
- goto done2;
- }
- }
- }
- done2:
-
- n_sample_times = QT_UINT32 (stts_data + 12);
- GST_LOG_OBJECT (qtdemux, "%u timestamp blocks", n_sample_times);
- timestamp = 0;
- stream->min_duration = 0;
- time = 0;
- index = 0;
- stts_data += 16;
- for (i = 0; i < n_sample_times; i++) {
- guint32 n;
- guint32 duration;
-
- n = QT_UINT32 (stts_data);
- stts_data += 4;
- duration = QT_UINT32 (stts_data);
- stts_data += 4;
- GST_LOG_OBJECT (qtdemux, "block %d, %u timestamps, duration %u ", i, n,
- duration);
-
- /* take first duration for fps */
- if (G_UNLIKELY (stream->min_duration == 0))
- stream->min_duration = duration;
-
- for (j = 0; j < n; j++) {
- GST_DEBUG_OBJECT (qtdemux,
- "sample %d: index %d, timestamp %" GST_TIME_FORMAT, index, j,
- GST_TIME_ARGS (timestamp));
-
- samples[index].timestamp = timestamp;
- /* add non-scaled values to avoid rounding errors */
- time += duration;
- timestamp = gst_util_uint64_scale (time, GST_SECOND, stream->timescale);
- samples[index].duration = timestamp - samples[index].timestamp;
-
- index++;
- if (G_UNLIKELY (index >= n_samples))
- goto done3;
- }
- }
- /* fill up empty timestamps with the last timestamp, this can happen when
- * the last samples do not decode and so we don't have timestamps for them.
- * We however look at the last timestamp to estimate the track length so we
- * need something in here. */
- for (; index < n_samples; index++) {
- GST_DEBUG_OBJECT (qtdemux, "fill sample %d: timestamp %" GST_TIME_FORMAT,
- index, GST_TIME_ARGS (timestamp));
- samples[index].timestamp = timestamp;
- samples[index].duration = -1;
- }
- done3:
-
- /* sample sync, can be NULL */
- stss = qtdemux_tree_get_child_by_type (stbl, FOURCC_stss);
-
- if (stss) {
- /* mark keyframes */
- guint32 n_sample_syncs;
- const guint8 *stss_p = (guint8 *) stss->data;
-
- stss_p += 12;
- n_sample_syncs = QT_UINT32 (stss_p);
- if (n_sample_syncs == 0) {
- stream->all_keyframe = TRUE;
- } else {
- for (i = 0; i < n_sample_syncs; i++) {
- stss_p += 4;
- /* note that the first sample is index 1, not 0 */
- index = QT_UINT32 (stss_p);
- if (G_LIKELY (index > 0 && index <= n_samples))
- samples[index - 1].keyframe = TRUE;
- }
- }
- stps = qtdemux_tree_get_child_by_type (stbl, FOURCC_stps);
- if (stps) {
- /* stps marks partial sync frames like open GOP I-Frames */
- guint32 n_sample_syncs;
- const guint8 *stps_p = (guint8 *) stps->data;
-
- stps_p += 12;
- n_sample_syncs = QT_UINT32 (stps_p);
- if (n_sample_syncs != 0) {
- /* no entries, the stss table contains the real sync
- * samples */
- } else {
- for (i = 0; i < n_sample_syncs; i++) {
- stps_p += 4;
- /* note that the first sample is index 1, not 0 */
- index = QT_UINT32 (stps_p);
- if (G_LIKELY (index > 0 && index <= n_samples))
- samples[index - 1].keyframe = TRUE;
- }
- }
- }
- } else {
- /* no stss, all samples are keyframes */
- stream->all_keyframe = TRUE;
- }
- } else {
- GST_DEBUG_OBJECT (qtdemux,
- "stsz sample_size %d != 0, treating chunks as samples", sample_size);
- /* treat chunks as samples */
- if (stco) {
- n_samples = QT_UINT32 (stco_data + 12);
- } else {
- n_samples = QT_UINT32 (co64_data + 12);
- }
-
- if (n_samples == 0)
- goto no_samples;
- else if (n_samples < 0)
- goto corrupt_file;
-
- GST_DEBUG_OBJECT (qtdemux, "allocating n_samples %d", n_samples);
-
- samples = g_try_new0 (QtDemuxSample, n_samples);
- if (samples == NULL)
- goto out_of_memory;
-
- stream->n_samples = n_samples;
- stream->samples = samples;
-
- n_samples_per_chunk = QT_UINT32 (stsc_data + 12);
- GST_DEBUG_OBJECT (qtdemux, "n_samples_per_chunk %d", n_samples_per_chunk);
- sample_index = 0;
- timestamp = 0;
- for (i = 0; i < n_samples_per_chunk; i++) {
- guint32 first_chunk, last_chunk;
- guint32 samples_per_chunk;
-
- first_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 0) - 1;
- /* the last chunk of each entry is calculated by taking the first chunk
- * of the next entry; except if there is no next, where we fake it with
- * INT_MAX */
- if (i == n_samples_per_chunk - 1) {
- last_chunk = G_MAXUINT32;
- } else {
- last_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 12) - 1;
- }
- samples_per_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 4);
-
- GST_LOG_OBJECT (qtdemux,
- "entry %d has first_chunk %d, last_chunk %d, samples_per_chunk %d", i,
- first_chunk, last_chunk, samples_per_chunk);
-
- for (j = first_chunk; j < last_chunk; j++) {
- guint64 chunk_offset;
-
- if (j >= n_samples)
- goto done;
-
- if (stco) {
- chunk_offset = QT_UINT32 (stco_data + 16 + j * 4);
- } else {
- chunk_offset = QT_UINT64 (co64_data + 16 + j * 8);
- }
- GST_LOG_OBJECT (qtdemux,
- "Creating entry %d with offset %" G_GUINT64_FORMAT, j,
- chunk_offset);
-
- samples[j].offset = chunk_offset;
-
- if (stream->samples_per_frame * stream->bytes_per_frame) {
- samples[j].size = (samples_per_chunk * stream->n_channels) /
- stream->samples_per_frame * stream->bytes_per_frame;
- } else {
- samples[j].size = samples_per_chunk;
- }
-
- GST_DEBUG_OBJECT (qtdemux, "sample %d: timestamp %" GST_TIME_FORMAT
- ", size %u", j, GST_TIME_ARGS (timestamp), samples[j].size);
-
- samples[j].timestamp = timestamp;
- sample_index += samples_per_chunk;
-
- timestamp = gst_util_uint64_scale (sample_index,
- GST_SECOND, stream->timescale);
- samples[j].duration = timestamp - samples[j].timestamp;
-
- samples[j].keyframe = TRUE;
- }
- }
- }
-
- /* composition time to sample */
- if ((ctts = qtdemux_tree_get_child_by_type (stbl, FOURCC_ctts))) {
- const guint8 *ctts_data, *ctts_p;
- guint32 n_entries;
- guint32 count;
- gint32 soffset;
-
- ctts_data = (const guint8 *) ctts->data;
- n_entries = QT_UINT32 (ctts_data + 12);
-
- /* Fill in the pts_offsets */
- index = 0;
- ctts_p = ctts_data + 16;
- /* FIXME: make sure we don't read beyond the atom size/boundary */
- for (i = 0; i < n_entries; i++) {
- count = QT_UINT32 (ctts_p);
- ctts_p += 4;
- soffset = QT_UINT32 (ctts_p);
- ctts_p += 4;
- for (j = 0; j < count; j++) {
- /* we operate with very small soffset values here, it shouldn't overflow */
- samples[index].pts_offset = soffset * GST_SECOND / stream->timescale;
- index++;
- if (G_UNLIKELY (index >= n_samples))
- goto done;
- }
- }
- }
-done:
- return TRUE;
-
-/* ERRORS */
-corrupt_file:
- {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file is corrupt and cannot be played.")), (NULL));
- return FALSE;
- }
-no_samples:
- {
- GST_WARNING_OBJECT (qtdemux, "stream has no samples");
- return FALSE;
- }
-out_of_memory:
- {
- GST_WARNING_OBJECT (qtdemux, "failed to allocate %d samples", n_samples);
- return FALSE;
- }
-}
-
-/* collect all segment info for @stream.
- */
-static gboolean
-qtdemux_parse_segments (GstQTDemux * qtdemux, QtDemuxStream * stream,
- GNode * trak)
-{
- GNode *edts;
-
- /* parse and prepare segment info from the edit list */
- GST_DEBUG_OBJECT (qtdemux, "looking for edit list container");
- stream->n_segments = 0;
- stream->segments = NULL;
- if ((edts = qtdemux_tree_get_child_by_type (trak, FOURCC_edts))) {
- GNode *elst;
- gint n_segments;
- gint i, count;
- guint64 time, stime;
- guint8 *buffer;
-
- GST_DEBUG_OBJECT (qtdemux, "looking for edit list");
- if (!(elst = qtdemux_tree_get_child_by_type (edts, FOURCC_elst)))
- goto done;
-
- buffer = elst->data;
-
- n_segments = QT_UINT32 (buffer + 12);
-
- /* we might allocate a bit too much, at least allocate 1 segment */
- stream->segments = g_new (QtDemuxSegment, MAX (n_segments, 1));
-
- /* segments always start from 0 */
- time = 0;
- stime = 0;
- count = 0;
- for (i = 0; i < n_segments; i++) {
- guint64 duration;
- guint64 media_time;
- QtDemuxSegment *segment;
- guint32 rate_int;
-
- media_time = QT_UINT32 (buffer + 20 + i * 12);
-
- /* -1 media time is an empty segment, just ignore it */
- if (media_time == G_MAXUINT32)
- continue;
-
- duration = QT_UINT32 (buffer + 16 + i * 12);
-
- segment = &stream->segments[count++];
-
- /* time and duration expressed in global timescale */
- segment->time = stime;
- /* add non scaled values so we don't cause roundoff errors */
- time += duration;
- stime = gst_util_uint64_scale (time, GST_SECOND, qtdemux->timescale);
- segment->stop_time = stime;
- segment->duration = stime - segment->time;
- /* media_time expressed in stream timescale */
- segment->media_start =
- gst_util_uint64_scale (media_time, GST_SECOND, stream->timescale);
- segment->media_stop = segment->media_start + segment->duration;
- rate_int = GST_READ_UINT32_BE (buffer + 24 + i * 12);
-
- if (rate_int <= 1) {
- /* 0 is not allowed, some programs write 1 instead of the floating point
- * value */
- GST_WARNING_OBJECT (qtdemux, "found suspicious rate %" G_GUINT32_FORMAT,
- rate_int);
- segment->rate = 1;
- } else {
- segment->rate = rate_int / 65536.0;
- }
-
- GST_DEBUG_OBJECT (qtdemux, "created segment %d time %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT ", media_time %" GST_TIME_FORMAT
- ", rate %g, (%d)", i, GST_TIME_ARGS (segment->time),
- GST_TIME_ARGS (segment->duration),
- GST_TIME_ARGS (segment->media_start), segment->rate, rate_int);
- }
- GST_DEBUG_OBJECT (qtdemux, "found %d non-empty segments", count);
- stream->n_segments = count;
- }
-done:
-
- /* push based does not handle segments, so act accordingly here,
- * and warn if applicable */
- if (!qtdemux->pullbased) {
- GST_WARNING_OBJECT (qtdemux, "streaming; discarding edit list segments");
- /* remove and use default one below, we stream like it anyway */
- g_free (stream->segments);
- stream->segments = NULL;
- stream->n_segments = 0;
- }
-
- /* no segments, create one to play the complete trak */
- if (stream->n_segments == 0) {
- GstClockTime stream_duration = 0;
-
- if (stream->segments == NULL)
- stream->segments = g_new (QtDemuxSegment, 1);
-
- /* samples know best */
- if (stream->n_samples > 0) {
- stream_duration =
- stream->samples[stream->n_samples - 1].timestamp +
- stream->samples[stream->n_samples - 1].pts_offset +
- stream->samples[stream->n_samples - 1].duration;
- }
-
- stream->segments[0].time = 0;
- stream->segments[0].stop_time = stream_duration;
- stream->segments[0].duration = stream_duration;
- stream->segments[0].media_start = 0;
- stream->segments[0].media_stop = stream_duration;
- stream->segments[0].rate = 1.0;
-
- GST_DEBUG_OBJECT (qtdemux, "created dummy segment %" GST_TIME_FORMAT,
- GST_TIME_ARGS (stream_duration));
- stream->n_segments = 1;
- }
- GST_DEBUG_OBJECT (qtdemux, "using %d segments", stream->n_segments);
-
- return TRUE;
-}
-
-/* parse the traks.
- * With each track we associate a new QtDemuxStream that contains all the info
- * about the trak.
- * traks that do not decode to something (like strm traks) will not have a pad.
- */
-static gboolean
-qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
-{
- int offset;
- GNode *tkhd;
- GNode *mdia;
- GNode *mdhd;
- GNode *hdlr;
- GNode *minf;
- GNode *stbl;
- GNode *stsd;
- GNode *mp4a;
- GNode *mp4v;
- GNode *wave;
- GNode *esds;
- GNode *pasp;
- QtDemuxStream *stream;
- GstTagList *list = NULL;
- gchar *codec = NULL;
- const guint8 *stsd_data;
- guint32 version;
-
- stream = g_new0 (QtDemuxStream, 1);
- /* new streams always need a discont */
- stream->discont = TRUE;
- /* we enable clipping for raw audio/video streams */
- stream->need_clip = FALSE;
- stream->segment_index = -1;
- stream->time_position = 0;
- stream->sample_index = -1;
- stream->last_ret = GST_FLOW_OK;
-
- if (!(tkhd = qtdemux_tree_get_child_by_type (trak, FOURCC_tkhd)))
- goto corrupt_file;
-
- GST_LOG_OBJECT (qtdemux, "track[tkhd] version/flags: 0x%08x",
- QT_UINT32 ((guint8 *) tkhd->data + 8));
-
- if (!(mdia = qtdemux_tree_get_child_by_type (trak, FOURCC_mdia)))
- goto corrupt_file;
-
- if (!(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mdhd))) {
- /* be nice for some crooked mjp2 files that use mhdr for mdhd */
- if (qtdemux->major_brand != FOURCC_mjp2 ||
- !(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mhdr)))
- goto corrupt_file;
- }
-
- version = QT_UINT32 ((guint8 *) mdhd->data + 8);
- GST_LOG_OBJECT (qtdemux, "track version/flags: %08x", version);
- if (version == 0x01000000) {
- stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 28);
- stream->duration = QT_UINT64 ((guint8 *) mdhd->data + 32);
- } else {
- stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 20);
- stream->duration = QT_UINT32 ((guint8 *) mdhd->data + 24);
- }
-
- GST_LOG_OBJECT (qtdemux, "track timescale: %" G_GUINT32_FORMAT,
- stream->timescale);
- GST_LOG_OBJECT (qtdemux, "track duration: %" G_GUINT64_FORMAT,
- stream->duration);
-
- if (G_UNLIKELY (stream->timescale == 0 || qtdemux->timescale == 0))
- goto corrupt_file;
-
- if (qtdemux->duration != G_MAXINT32 && stream->duration != G_MAXINT32) {
- guint64 tdur1, tdur2;
-
- /* don't overflow */
- tdur1 = stream->timescale * (guint64) qtdemux->duration;
- tdur2 = qtdemux->timescale * (guint64) stream->duration;
-
- /* HACK:
- * some of those trailers, nowadays, have prologue images that are
- * themselves vide tracks as well. I haven't really found a way to
- * identify those yet, except for just looking at their duration. */
- if (tdur1 != 0 && (tdur2 * 10 / tdur1) < 2) {
- GST_WARNING_OBJECT (qtdemux,
- "Track shorter than 20%% (%" G_GUINT64_FORMAT "/%" G_GUINT32_FORMAT
- " vs. %" G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT ") of the stream "
- "found, assuming preview image or something; skipping track",
- stream->duration, stream->timescale, qtdemux->duration,
- qtdemux->timescale);
- g_free (stream);
- return TRUE;
- }
- }
-
- if (!(hdlr = qtdemux_tree_get_child_by_type (mdia, FOURCC_hdlr)))
- goto corrupt_file;
-
- GST_LOG_OBJECT (qtdemux, "track type: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (QT_FOURCC ((guint8 *) hdlr->data + 12)));
-
- stream->subtype = QT_FOURCC ((guint8 *) hdlr->data + 16);
- GST_LOG_OBJECT (qtdemux, "track subtype: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (stream->subtype));
-
- if (!(minf = qtdemux_tree_get_child_by_type (mdia, FOURCC_minf)))
- goto corrupt_file;
-
- if (!(stbl = qtdemux_tree_get_child_by_type (minf, FOURCC_stbl)))
- goto corrupt_file;
-
- /* parse stsd */
- if (!(stsd = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsd)))
- goto corrupt_file;
- stsd_data = (const guint8 *) stsd->data;
-
- if (stream->subtype == FOURCC_vide) {
- guint32 fourcc;
- const guint8 *tkhd_data = (const guint8 *) tkhd->data;
-
- stream->sampled = TRUE;
-
- /* version 1 uses some 64-bit ints */
- offset = (QT_UINT8 (tkhd_data + 8) == 1) ? 96 : 84;
- stream->display_width = (guint) QT_FP32 (tkhd_data + offset);
- stream->display_height = (guint) QT_FP32 (tkhd_data + offset + 4);
-
- offset = 16;
- stream->fourcc = fourcc = QT_FOURCC (stsd_data + offset + 4);
- GST_LOG_OBJECT (qtdemux, "st type: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
- stream->width = QT_UINT16 (stsd_data + offset + 32);
- stream->height = QT_UINT16 (stsd_data + offset + 34);
- stream->fps_n = 0; /* this is filled in later */
- stream->fps_d = 0; /* this is filled in later */
- stream->bits_per_sample = QT_UINT16 (stsd_data + offset + 82);
- stream->color_table_id = QT_UINT16 (stsd_data + offset + 84);
-
- GST_LOG_OBJECT (qtdemux, "frame count: %u",
- QT_UINT16 (stsd_data + offset + 48));
-
- if (fourcc == FOURCC_drms)
- goto error_encrypted;
-
- stream->caps =
- qtdemux_video_caps (qtdemux, stream, fourcc, stsd_data, &codec);
- if (codec) {
- list = gst_tag_list_new ();
- gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
- GST_TAG_VIDEO_CODEC, codec, NULL);
- g_free (codec);
- codec = NULL;
- }
-
- esds = NULL;
- pasp = NULL;
- mp4v = qtdemux_tree_get_child_by_type (stsd, FOURCC_mp4v);
- if (mp4v) {
- esds = qtdemux_tree_get_child_by_type (mp4v, FOURCC_esds);
- pasp = qtdemux_tree_get_child_by_type (mp4v, FOURCC_pasp);
- }
-
- if (pasp) {
- const guint8 *pasp_data = (const guint8 *) pasp->data;
-
- stream->par_w = QT_UINT32 (pasp_data + 8);
- stream->par_h = QT_UINT32 (pasp_data + 12);
- } else {
- stream->par_w = 0;
- stream->par_h = 0;
- }
-
- if (esds) {
- gst_qtdemux_handle_esds (qtdemux, stream, esds, list);
- } else {
- switch (fourcc) {
- case FOURCC_avc1:
- {
- gint len = QT_UINT32 (stsd_data) - 0x66;
- const guint8 *avc_data = stsd_data + 0x66;
-
- /* find avcC */
- while (len >= 0x8 &&
- QT_FOURCC (avc_data + 0x4) != FOURCC_avcC &&
- QT_UINT32 (avc_data) < len) {
- len -= QT_UINT32 (avc_data);
- avc_data += QT_UINT32 (avc_data);
- }
-
- /* parse, if found */
- if (len > 0x8 && QT_FOURCC (avc_data + 0x4) == FOURCC_avcC) {
- GstBuffer *buf;
- gint size;
-
- if (QT_UINT32 (avc_data) < len)
- size = QT_UINT32 (avc_data) - 0x8;
- else
- size = len - 0x8;
-
- GST_DEBUG_OBJECT (qtdemux, "found avcC codec_data in stsd");
-
- buf = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size);
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
- break;
- }
- case FOURCC_mjp2:
- {
- GNode *jp2h, *colr, *mjp2, *field, *prefix;
- const guint8 *data;
- guint32 fourcc = 0;
-
- GST_DEBUG_OBJECT (qtdemux, "found mjp2");
- /* some required atoms */
- mjp2 = qtdemux_tree_get_child_by_type (stsd, FOURCC_mjp2);
- if (!mjp2)
- break;
- jp2h = qtdemux_tree_get_child_by_type (mjp2, FOURCC_jp2h);
- if (!jp2h)
- break;
- colr = qtdemux_tree_get_child_by_type (jp2h, FOURCC_colr);
- if (!colr)
- break;
- GST_DEBUG_OBJECT (qtdemux, "found colr");
- /* try to extract colour space info */
- if (QT_UINT8 ((guint8 *) colr->data + 8) == 1) {
- switch (QT_UINT32 ((guint8 *) colr->data + 11)) {
- case 16:
- fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B');
- break;
- case 17:
- fourcc = GST_MAKE_FOURCC ('G', 'R', 'A', 'Y');
- break;
- case 18:
- fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V');
- break;
- default:
- break;
- }
- }
-
- if (fourcc)
- gst_caps_set_simple (stream->caps,
- "fourcc", GST_TYPE_FOURCC, fourcc, NULL);
-
- /* some optional atoms */
- field = qtdemux_tree_get_child_by_type (mjp2, FOURCC_fiel);
- prefix = qtdemux_tree_get_child_by_type (mjp2, FOURCC_jp2x);
-
- /* indicate possible fields in caps */
- if (field) {
- data = (guint8 *) field->data + 8;
- if (*data != 1)
- gst_caps_set_simple (stream->caps, "fields", G_TYPE_INT,
- (gint) * data, NULL);
- }
- /* add codec_data if provided */
- if (prefix) {
- GstBuffer *buf;
- gint len;
-
- GST_DEBUG_OBJECT (qtdemux, "found prefix data in stsd");
- data = prefix->data;
- len = QT_UINT32 (data);
- if (len > 0x8) {
- len -= 0x8;
- buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), data + 8, len);
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
- }
- break;
- }
- case FOURCC_SVQ3:
- case FOURCC_VP31:
- {
- GstBuffer *buf;
- gint len = QT_UINT32 (stsd_data);
-
- GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd");
-
- buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), stsd_data, len);
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- break;
- }
- case FOURCC_rle_:
- {
- gst_caps_set_simple (stream->caps,
- "depth", G_TYPE_INT, QT_UINT16 (stsd_data + offset + 82), NULL);
- break;
- }
- case FOURCC_XiTh:
- {
- GNode *xith, *xdxt;
-
- GST_DEBUG_OBJECT (qtdemux, "found XiTh");
- xith = qtdemux_tree_get_child_by_type (stsd, FOURCC_XiTh);
- if (!xith)
- break;
-
- xdxt = qtdemux_tree_get_child_by_type (xith, FOURCC_XdxT);
- if (!xdxt)
- break;
-
- GST_DEBUG_OBJECT (qtdemux, "found XdxT node");
- /* collect the headers and store them in a stream list so that we can
- * send them out first */
- qtdemux_parse_theora_extension (qtdemux, stream, xdxt);
- break;
- }
- default:
- break;
- }
- }
-
- GST_INFO_OBJECT (qtdemux,
- "type %" GST_FOURCC_FORMAT " caps %" GST_PTR_FORMAT,
- GST_FOURCC_ARGS (fourcc), stream->caps);
-
- } else if (stream->subtype == FOURCC_soun) {
- int version, samplesize;
- guint32 fourcc;
- int len;
- guint16 compression_id;
-
- len = QT_UINT32 (stsd_data + 16);
- GST_LOG_OBJECT (qtdemux, "stsd len: %d", len);
-
- stream->fourcc = fourcc = QT_FOURCC (stsd_data + 16 + 4);
- GST_LOG_OBJECT (qtdemux, "stsd type: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (stream->fourcc));
-
- offset = 32;
-
- version = QT_UINT32 (stsd_data + offset);
- stream->n_channels = QT_UINT16 (stsd_data + offset + 8);
- samplesize = QT_UINT16 (stsd_data + offset + 10);
- compression_id = QT_UINT16 (stsd_data + offset + 12);
- stream->rate = QT_FP32 (stsd_data + offset + 16);
-
- GST_LOG_OBJECT (qtdemux, "version/rev: %08x", version);
- GST_LOG_OBJECT (qtdemux, "vendor: %08x",
- QT_UINT32 (stsd_data + offset + 4));
- GST_LOG_OBJECT (qtdemux, "n_channels: %d", stream->n_channels);
- GST_LOG_OBJECT (qtdemux, "sample_size: %d", samplesize);
- GST_LOG_OBJECT (qtdemux, "compression_id: %d", compression_id);
- GST_LOG_OBJECT (qtdemux, "packet size: %d",
- QT_UINT16 (stsd_data + offset + 14));
- GST_LOG_OBJECT (qtdemux, "sample rate: %g", stream->rate);
-
- if (compression_id == 0xfffe)
- stream->sampled = TRUE;
-
- /* first assume uncompressed audio */
- stream->bytes_per_sample = samplesize / 8;
- stream->samples_per_frame = stream->n_channels;
- stream->bytes_per_frame = stream->n_channels * stream->bytes_per_sample;
- stream->samples_per_packet = stream->samples_per_frame;
- stream->bytes_per_packet = stream->bytes_per_sample;
-
- offset = 52;
- switch (fourcc) {
- /* Yes, these have to be hard-coded */
- case FOURCC_MAC6:
- {
- stream->samples_per_packet = 6;
- stream->bytes_per_packet = 1;
- stream->bytes_per_frame = 1 * stream->n_channels;
- stream->bytes_per_sample = 1;
- stream->samples_per_frame = 6 * stream->n_channels;
- break;
- }
- case FOURCC_MAC3:
- {
- stream->samples_per_packet = 3;
- stream->bytes_per_packet = 1;
- stream->bytes_per_frame = 1 * stream->n_channels;
- stream->bytes_per_sample = 1;
- stream->samples_per_frame = 3 * stream->n_channels;
- break;
- }
- case FOURCC_ima4:
- {
- stream->samples_per_packet = 64;
- stream->bytes_per_packet = 34;
- stream->bytes_per_frame = 34 * stream->n_channels;
- stream->bytes_per_sample = 2;
- stream->samples_per_frame = 64 * stream->n_channels;
- break;
- }
- case FOURCC_ulaw:
- case FOURCC_alaw:
- {
- stream->samples_per_packet = 1;
- stream->bytes_per_packet = 1;
- stream->bytes_per_frame = 1 * stream->n_channels;
- stream->bytes_per_sample = 1;
- stream->samples_per_frame = 1 * stream->n_channels;
- break;
- }
- case FOURCC_agsm:
- {
- stream->samples_per_packet = 160;
- stream->bytes_per_packet = 33;
- stream->bytes_per_frame = 33 * stream->n_channels;
- stream->bytes_per_sample = 2;
- stream->samples_per_frame = 160 * stream->n_channels;
- break;
- }
- default:
- break;
- }
-
- if (version == 0x00010000) {
- switch (fourcc) {
- case FOURCC_twos:
- case FOURCC_sowt:
- case FOURCC_raw_:
- break;
- default:
- {
- /* only parse extra decoding config for non-pcm audio */
- stream->samples_per_packet = QT_UINT32 (stsd_data + offset);
- stream->bytes_per_packet = QT_UINT32 (stsd_data + offset + 4);
- stream->bytes_per_frame = QT_UINT32 (stsd_data + offset + 8);
- stream->bytes_per_sample = QT_UINT32 (stsd_data + offset + 12);
-
- GST_LOG_OBJECT (qtdemux, "samples/packet: %d",
- stream->samples_per_packet);
- GST_LOG_OBJECT (qtdemux, "bytes/packet: %d",
- stream->bytes_per_packet);
- GST_LOG_OBJECT (qtdemux, "bytes/frame: %d",
- stream->bytes_per_frame);
- GST_LOG_OBJECT (qtdemux, "bytes/sample: %d",
- stream->bytes_per_sample);
-
- if (!stream->sampled && stream->bytes_per_packet) {
- stream->samples_per_frame = (stream->bytes_per_frame /
- stream->bytes_per_packet) * stream->samples_per_packet;
- GST_LOG_OBJECT (qtdemux, "samples/frame: %d",
- stream->samples_per_frame);
- }
- break;
- }
- }
- } else if (version == 0x00020000) {
- union
- {
- gdouble fp;
- guint64 val;
- } qtfp;
-
- stream->samples_per_packet = QT_UINT32 (stsd_data + offset);
- qtfp.val = QT_UINT64 (stsd_data + offset + 4);
- stream->rate = qtfp.fp;
- stream->n_channels = QT_UINT32 (stsd_data + offset + 12);
-
- GST_LOG_OBJECT (qtdemux, "samples/packet: %d",
- stream->samples_per_packet);
- GST_LOG_OBJECT (qtdemux, "sample rate: %g", stream->rate);
- GST_LOG_OBJECT (qtdemux, "n_channels: %d", stream->n_channels);
-
- } else {
- GST_WARNING_OBJECT (qtdemux, "unknown version %08x", version);
- }
-
- if (fourcc == FOURCC_drms)
- goto error_encrypted;
-
- stream->caps = qtdemux_audio_caps (qtdemux, stream, fourcc, NULL, 0,
- &codec);
-
- switch (fourcc) {
- case FOURCC_in24:
- {
- GNode *enda;
- GNode *in24;
-
- in24 = qtdemux_tree_get_child_by_type (stsd, FOURCC_in24);
-
- enda = qtdemux_tree_get_child_by_type (in24, FOURCC_enda);
- if (!enda) {
- wave = qtdemux_tree_get_child_by_type (in24, FOURCC_wave);
- if (wave)
- enda = qtdemux_tree_get_child_by_type (wave, FOURCC_enda);
- }
- if (enda) {
- gst_caps_set_simple (stream->caps,
- "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL);
- }
- break;
- }
- default:
- break;
- }
-
- if (codec) {
- list = gst_tag_list_new ();
- gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
- GST_TAG_AUDIO_CODEC, codec, NULL);
- g_free (codec);
- codec = NULL;
- }
-
- mp4a = qtdemux_tree_get_child_by_type (stsd, FOURCC_mp4a);
- wave = NULL;
- esds = NULL;
- if (mp4a) {
- wave = qtdemux_tree_get_child_by_type (mp4a, FOURCC_wave);
- if (wave)
- esds = qtdemux_tree_get_child_by_type (wave, FOURCC_esds);
- if (!esds)
- esds = qtdemux_tree_get_child_by_type (mp4a, FOURCC_esds);
- }
-
- if (esds) {
- gst_qtdemux_handle_esds (qtdemux, stream, esds, list);
- } else {
- switch (fourcc) {
-#if 0
- /* FIXME: what is in the chunk? */
- case FOURCC_QDMC:
- {
- gint len = QT_UINT32 (stsd_data);
-
- /* seems to be always = 116 = 0x74 */
- break;
- }
-#endif
- case FOURCC_QDM2:
- {
- gint len = QT_UINT32 (stsd_data);
-
- if (len > 0x4C) {
- GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x4C);
-
- memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x4C, len - 0x4C);
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
- gst_caps_set_simple (stream->caps,
- "samplesize", G_TYPE_INT, samplesize, NULL);
- break;
- }
- case FOURCC_alac:
- {
- gint len = QT_UINT32 (stsd_data);
-
- if (len > 0x34) {
- GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x34);
-
- memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x34, len - 0x34);
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
- gst_caps_set_simple (stream->caps,
- "samplesize", G_TYPE_INT, samplesize, NULL);
- break;
- }
- case FOURCC_samr:
- {
- gint len = QT_UINT32 (stsd_data);
-
- if (len > 0x34) {
- GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x34);
-
- memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x34, len - 0x34);
-
- gst_caps_set_simple (stream->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
- break;
- }
- default:
- break;
- }
- }
- GST_INFO_OBJECT (qtdemux,
- "type %" GST_FOURCC_FORMAT " caps %" GST_PTR_FORMAT,
- GST_FOURCC_ARGS (fourcc), stream->caps);
-
- } else if (stream->subtype == FOURCC_strm) {
- guint32 fourcc;
-
- stream->fourcc = fourcc = QT_FOURCC (stsd_data + 16 + 4);
- GST_LOG_OBJECT (qtdemux, "stsd type: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
- if (fourcc != FOURCC_rtsp) {
- GST_INFO_OBJECT (qtdemux, "unhandled stream type %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- goto unknown_stream;
- }
- stream->sampled = TRUE;
- } else if (stream->subtype == FOURCC_subp) {
- guint32 fourcc;
-
- stream->sampled = TRUE;
-
- offset = 16;
- stream->fourcc = fourcc = QT_FOURCC (stsd_data + offset + 4);
- GST_LOG_OBJECT (qtdemux, "st type: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
- stream->caps =
- qtdemux_subp_caps (qtdemux, stream, fourcc, stsd_data, &codec);
- } else {
- goto unknown_stream;
- }
-
- /* promote to sampled format */
- if (stream->fourcc == FOURCC_samr) {
- /* force mono 8000 Hz for AMR */
- stream->sampled = TRUE;
- stream->n_channels = 1;
- stream->rate = 8000;
- } else if (stream->fourcc == FOURCC_sawb) {
- /* force mono 16000 Hz for AMR-WB */
- stream->sampled = TRUE;
- stream->n_channels = 1;
- stream->rate = 16000;
- } else if (stream->fourcc == FOURCC_mp4a) {
- stream->sampled = TRUE;
- }
-
- /* collect sample information */
- if (!qtdemux_parse_samples (qtdemux, stream, stbl))
- goto samples_failed;
-
- /* configure segments */
- if (!qtdemux_parse_segments (qtdemux, stream, trak))
- goto segments_failed;
-
- /* now we are ready to add the stream */
- gst_qtdemux_add_stream (qtdemux, stream, list);
-
- return TRUE;
-
-/* ERRORS */
-corrupt_file:
- {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE,
- (_("This file is corrupt and cannot be played.")), (NULL));
- g_free (stream);
- return FALSE;
- }
-error_encrypted:
- {
- GST_ELEMENT_ERROR (qtdemux, STREAM, DECRYPT, (NULL), (NULL));
- g_free (stream);
- return FALSE;
- }
-samples_failed:
- {
- /* we posted an error already */
- g_free (stream);
- return FALSE;
- }
-segments_failed:
- {
- /* we posted an error already */
- g_free (stream);
- return FALSE;
- }
-unknown_stream:
- {
- GST_INFO_OBJECT (qtdemux, "unknown subtype %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (stream->subtype));
- g_free (stream);
- return TRUE;
- }
-}
-
-static inline gboolean
-qtdemux_is_string_3gp (GstQTDemux * qtdemux, guint32 fourcc)
-{
- /* Detect if the tag must be handled as 3gpp - i18n metadata. The first
- * check is for catching all the possible brands, e.g. 3gp4,3gp5,3gg6,.. and
- * handling properly the tags present in more than one brand.*/
- return ((qtdemux->major_brand & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
- GST_MAKE_FOURCC ('3', 'g', 0, 0)
- && (fourcc == FOURCC_cprt || fourcc == FOURCC_gnre
- || fourcc == FOURCC_kywd)) || fourcc == FOURCC_titl
- || fourcc == FOURCC_dscp || fourcc == FOURCC_perf || fourcc == FOURCC_auth
- || fourcc == FOURCC_albm;
-}
-
-static void
-qtdemux_tag_add_location (GstQTDemux * qtdemux, const char *tag,
- const char *dummy, GNode * node)
-{
- const gchar *env_vars[] = { "GST_QT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
- int offset;
- char *name;
- gchar *data;
- gdouble longitude, latitude, altitude;
-
- data = node->data;
- offset = 14;
-
- /* TODO: language code skipped */
-
- name = gst_tag_freeform_string_to_utf8 (data + offset, -1, env_vars);
-
- if (!name) {
- /* do not alarm in trivial case, but bail out otherwise */
- if (*(data + offset) != 0) {
- GST_DEBUG_OBJECT (qtdemux, "failed to convert %s tag to UTF-8, "
- "giving up", tag);
- }
- } else {
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- GST_TAG_GEO_LOCATION_NAME, name, NULL);
- offset += strlen (name);
- g_free (name);
- }
-
- /* +1 +1 = skip null-terminator and location role byte */
- offset += 1 + 1;
- longitude = QT_FP32 (data + offset);
-
- offset += 4;
- latitude = QT_FP32 (data + offset);
-
- offset += 4;
- altitude = QT_FP32 (data + offset);
-
- /* one invalid means all are invalid */
- if (longitude >= -180.0 && longitude <= 180.0 &&
- latitude >= -90.0 && latitude <= 90.0) {
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- GST_TAG_GEO_LOCATION_LATITUDE, latitude,
- GST_TAG_GEO_LOCATION_LONGITUDE, longitude,
- GST_TAG_GEO_LOCATION_ELEVATION, altitude, NULL);
- }
-
- /* TODO: no GST_TAG_, so astronomical body and additional notes skipped */
-}
-
-
-static void
-qtdemux_tag_add_year (GstQTDemux * qtdemux, const char *tag, const char *dummy,
- GNode * node)
-{
- guint16 y;
- GDate *date;
-
- y = QT_UINT16 ((guint8 *) node->data + 12);
- GST_DEBUG_OBJECT (qtdemux, "year: %u", y);
-
- date = g_date_new_dmy (1, 1, y);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, date, NULL);
- g_date_free (date);
-}
-
-static void
-qtdemux_tag_add_classification (GstQTDemux * qtdemux, const char *tag,
- const char *dummy, GNode * node)
-{
- int offset;
- char *tag_str = NULL;
- guint8 *entity;
- guint16 table;
-
-
- offset = 12;
- entity = (guint8 *) node->data + offset;
-
- offset += 4;
- table = QT_UINT16 ((guint8 *) node->data + offset);
-
- /* Language code skipped */
-
- offset += 4;
-
- /* Tag format: "XXXX://Y[YYYY]/classification info string"
- * XXXX: classification entity, fixed length 4 chars.
- * Y[YYYY]: classification table, max 5 chars.
- */
- tag_str = g_strdup_printf ("----://%u/%s",
- table, (char *) node->data + offset);
-
- /* memcpy To be sure we're preserving byte order */
- memcpy (tag_str, entity, 4);
- GST_DEBUG_OBJECT (qtdemux, "classification info: %s", tag_str);
-
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_APPEND, tag,
- tag_str, NULL);
-
- g_free (tag_str);
-}
-
-static void
-qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, const char *dummy,
- GNode * node)
-{
- const gchar *env_vars[] = { "GST_QT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
- GNode *data;
- char *s;
- int len;
- guint32 type;
- int offset;
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- if (type == 0x00000001) {
- s = gst_tag_freeform_string_to_utf8 ((char *) data->data + 16, len - 16,
- env_vars);
- if (s) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag %s", GST_STR_NULL (s));
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, s,
- NULL);
- g_free (s);
- } else {
- GST_DEBUG_OBJECT (qtdemux, "failed to convert %s tag to UTF-8", tag);
- }
- }
- } else {
- len = QT_UINT32 (node->data);
- type = QT_UINT32 ((guint8 *) node->data + 4);
- if ((type >> 24) == 0xa9) {
- /* Type starts with the (C) symbol, so the next 32 bits are
- * the language code, which we ignore */
- offset = 12;
- GST_DEBUG_OBJECT (qtdemux, "found international text tag");
- } else if (qtdemux_is_string_3gp (qtdemux,
- QT_FOURCC ((guint8 *) node->data + 4))) {
- offset = 14;
- /* 16-bit Language code is ignored here as well */
- GST_DEBUG_OBJECT (qtdemux, "found 3gpp text tag");
- } else {
- offset = 8;
- GST_DEBUG_OBJECT (qtdemux, "found normal text tag");
- }
- s = gst_tag_freeform_string_to_utf8 ((char *) node->data + offset,
- len - offset, env_vars);
- if (s) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag %s", GST_STR_NULL (s));
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, s, NULL);
- g_free (s);
- } else {
- GST_DEBUG_OBJECT (qtdemux, "failed to convert %s tag to UTF-8", tag);
- }
- }
-}
-
-static void
-qtdemux_tag_add_keywords (GstQTDemux * qtdemux, const char *tag,
- const char *dummy, GNode * node)
-{
- const gchar *env_vars[] = { "GST_QT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
- guint8 *data;
- char *s, *t, *k = NULL;
- int len;
- int offset;
- int count;
-
- /* re-route to normal string tag if not 3GP */
- if (!qtdemux_is_string_3gp (qtdemux, FOURCC_kywd))
- {
- qtdemux_tag_add_str (qtdemux, tag, dummy, node);
- return ;
- }
-
- GST_DEBUG_OBJECT (qtdemux, "found 3gpp keyword tag");
-
- data = node->data;
-
- len = QT_UINT32 (data);
- if (len < 15)
- goto short_read;
-
- count = QT_UINT8 (data + 14);
- offset = 15;
- for (; count; count--) {
- gint slen;
-
- if (offset + 1 > len)
- goto short_read;
- slen = QT_UINT8 (data + offset);
- offset += 1;
- if (offset + slen > len)
- goto short_read;
- s = gst_tag_freeform_string_to_utf8 ((char *) node->data + offset,
- slen, env_vars);
- if (s) {
- GST_DEBUG_OBJECT (qtdemux, "adding keyword %s", GST_STR_NULL (s));
- if (k) {
- t = g_strjoin (",", k, s, NULL);
- g_free (s);
- g_free (k);
- k = t;
- } else {
- k = s;
- }
- } else {
- GST_DEBUG_OBJECT (qtdemux, "failed to convert keyword to UTF-8");
- }
- offset += slen;
- }
-
-done:
- if (k) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag %s", GST_STR_NULL (k));
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, k, NULL);
- }
- g_free (k);
-
- return;
-
- /* ERRORS */
-short_read:
- {
- GST_DEBUG_OBJECT (qtdemux, "short read parsing 3GP keywords");
- goto done;
- }
-}
-
-static void
-qtdemux_tag_add_num (GstQTDemux * qtdemux, const char *tag1,
- const char *tag2, GNode * node)
-{
- GNode *data;
- int len;
- int type;
- int n1, n2;
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- if (type == 0x00000000 && len >= 22) {
- n1 = QT_UINT16 ((guint8 *) data->data + 18);
- n2 = QT_UINT16 ((guint8 *) data->data + 20);
- if (n1 > 0) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag %s=%d", tag1, n1);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- tag1, n1, NULL);
- }
- if (n2 > 0) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag %s=%d", tag2, n2);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- tag2, n2, NULL);
- }
- }
- }
-}
-
-static void
-qtdemux_tag_add_tmpo (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
- GNode * node)
-{
- GNode *data;
- int len;
- int type;
- int n1;
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- GST_DEBUG_OBJECT (qtdemux, "have tempo tag, type=%d,len=%d", type, len);
- /* some files wrongly have a type 0x0f=15, but it should be 0x15 */
- if ((type == 0x00000015 || type == 0x0000000f) && len >= 18) {
- n1 = QT_UINT16 ((guint8 *) data->data + 16);
- if (n1) {
- /* do not add bpm=0 */
- GST_DEBUG_OBJECT (qtdemux, "adding tag %d", n1);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- tag1, (gdouble) n1, NULL);
- }
- }
- }
-}
-
-static void
-qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
- GNode * node)
-{
- GNode *data;
- int len;
- int type;
- GstBuffer *buf;
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- GST_DEBUG_OBJECT (qtdemux, "have covr tag, type=%d,len=%d", type, len);
- if ((type == 0x0000000d || type == 0x0000000e) && len > 16) {
- if ((buf = gst_tag_image_data_to_image_buffer ((guint8 *) data->data + 16,
- len - 16, GST_TAG_IMAGE_TYPE_NONE))) {
- GST_DEBUG_OBJECT (qtdemux, "adding tag size %d", len - 16);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- tag1, buf, NULL);
- gst_buffer_unref (buf);
- }
- }
- }
-}
-
-static void
-qtdemux_tag_add_date (GstQTDemux * qtdemux, const char *tag, const char *dummy,
- GNode * node)
-{
- GNode *data;
- char *s;
- int len;
- int type;
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- if (type == 0x00000001) {
- guint y, m = 1, d = 1;
- gint ret;
-
- s = g_strndup ((char *) data->data + 16, len - 16);
- GST_DEBUG_OBJECT (qtdemux, "adding date '%s'", s);
- ret = sscanf (s, "%u-%u-%u", &y, &m, &d);
- if (ret >= 1 && y > 1500 && y < 3000) {
- GDate *date;
-
- date = g_date_new_dmy (d, m, y);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag,
- date, NULL);
- g_date_free (date);
- } else {
- GST_DEBUG_OBJECT (qtdemux, "could not parse date string '%s'", s);
- }
- g_free (s);
- }
- }
-}
-
-static void
-qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, const char *dummy,
- GNode * node)
-{
- static const gchar *genres[] = {
- "N/A", "Blues", "Classic Rock", "Country", "Dance", "Disco",
- "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
- "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno",
- "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
- "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal",
- "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental",
- "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise",
- "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative",
- "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic",
- "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
- "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
- "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American",
- "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes",
- "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka",
- "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
- "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob",
- "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
- "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
- "Symphonic Rock", "Slow Rock", "Big Band", "Chorus",
- "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
- "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass",
- "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango",
- "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul",
- "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella",
- "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club House",
- "Hardcore", "Terror", "Indie", "BritPop", "NegerPunk",
- "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal",
- "Black Metal", "Crossover", "Contemporary C", "Christian Rock",
- "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "SynthPop"
- };
- GNode *data;
- int len;
- int type;
- int n;
-
- /* re-route to normal string tag if 3GP */
- if (qtdemux_is_string_3gp (qtdemux, FOURCC_gnre))
- {
- qtdemux_tag_add_str (qtdemux, tag, dummy, node);
- return;
- }
-
- data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
- if (data) {
- len = QT_UINT32 (data->data);
- type = QT_UINT32 ((guint8 *) data->data + 8);
- if (type == 0x00000000 && len >= 18) {
- n = QT_UINT16 ((guint8 *) data->data + 16);
- if (n > 0 && n < sizeof (genres) / sizeof (char *)) {
- GST_DEBUG_OBJECT (qtdemux, "adding %d [%s]", n, genres[n]);
- gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
- tag, genres[n], NULL);
- }
- }
- }
-}
-
-typedef void (*GstQTDemuxAddTagFunc) (GstQTDemux * demux,
- const char *tag, const char *tag_bis, GNode * node);
-
-static const struct
-{
- guint32 fourcc;
- const gchar *gst_tag;
- const gchar *gst_tag_bis;
- const GstQTDemuxAddTagFunc func;
-} add_funcs[] = {
- {
- FOURCC__nam, GST_TAG_TITLE, NULL, qtdemux_tag_add_str}, {
- FOURCC_titl, GST_TAG_TITLE, NULL, qtdemux_tag_add_str}, {
- FOURCC__grp, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
- FOURCC__wrt, GST_TAG_COMPOSER, NULL, qtdemux_tag_add_str}, {
- FOURCC__ART, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
- FOURCC_perf, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
- FOURCC_auth, GST_TAG_COMPOSER, NULL, qtdemux_tag_add_str}, {
- FOURCC__alb, GST_TAG_ALBUM, NULL, qtdemux_tag_add_str}, {
- FOURCC_albm, GST_TAG_ALBUM, NULL, qtdemux_tag_add_str}, {
- FOURCC_cprt, GST_TAG_COPYRIGHT, NULL, qtdemux_tag_add_str}, {
- FOURCC__cpy, GST_TAG_COPYRIGHT, NULL, qtdemux_tag_add_str}, {
- FOURCC__cmt, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, {
- FOURCC__des, GST_TAG_DESCRIPTION, NULL, qtdemux_tag_add_str}, {
- FOURCC_dscp, GST_TAG_DESCRIPTION, NULL, qtdemux_tag_add_str}, {
- FOURCC__day, GST_TAG_DATE, NULL, qtdemux_tag_add_date}, {
- FOURCC_yrrc, GST_TAG_DATE, NULL, qtdemux_tag_add_year}, {
- FOURCC__too, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, {
- FOURCC__inf, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, {
- FOURCC_trkn, GST_TAG_TRACK_NUMBER, GST_TAG_TRACK_COUNT, qtdemux_tag_add_num}, {
- FOURCC_disk, GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_ALBUM_VOLUME_COUNT,
- qtdemux_tag_add_num}, {
- FOURCC_disc, GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_ALBUM_VOLUME_COUNT,
- qtdemux_tag_add_num}, {
- FOURCC__gen, GST_TAG_GENRE, NULL, qtdemux_tag_add_str}, {
- FOURCC_gnre, GST_TAG_GENRE, NULL, qtdemux_tag_add_gnre}, {
- FOURCC_tmpo, GST_TAG_BEATS_PER_MINUTE, NULL, qtdemux_tag_add_tmpo}, {
- FOURCC_covr, GST_TAG_PREVIEW_IMAGE, NULL, qtdemux_tag_add_covr}, {
- FOURCC_kywd, GST_TAG_KEYWORDS, NULL, qtdemux_tag_add_keywords}, {
- FOURCC_keyw, GST_TAG_KEYWORDS, NULL, qtdemux_tag_add_str}, {
- FOURCC__enc, GST_TAG_ENCODER, NULL, qtdemux_tag_add_str}, {
- FOURCC_loci, GST_TAG_GEO_LOCATION_NAME, NULL, qtdemux_tag_add_location}, {
- FOURCC_clsf, GST_QT_DEMUX_CLASSIFICATION_TAG, NULL,
- qtdemux_tag_add_classification}
-};
-
-static void
-qtdemux_tag_add_blob (GNode * node, GstQTDemux * demux)
-{
- gint len;
- guint8 *data;
- GstBuffer *buf;
- gchar *media_type, *style;
- GstCaps *caps;
- guint i;
- guint8 ndata[4];
-
- data = node->data;
- len = QT_UINT32 (data);
- buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), data, len);
-
- /* heuristic to determine style of tag */
- if (QT_FOURCC (data + 4) == FOURCC_____ ||
- (len > 8 + 12 && QT_FOURCC (data + 12) == FOURCC_data))
- style = "itunes";
- else if (demux->major_brand == FOURCC_qt__)
- style = "quicktime";
- /* fall back to assuming iso/3gp tag style */
- else
- style = "iso";
-
- /* santize the name for the caps. */
- for (i = 0; i < 4; i++) {
- guint8 d = data[4 + i];
- if (g_ascii_isalnum (d))
- ndata[i] = g_ascii_tolower (d);
- else
- ndata[i] = '_';
- }
-
- media_type = g_strdup_printf ("application/x-gst-qt-%c%c%c%c-tag",
- ndata[0], ndata[1], ndata[2], ndata[3]);
- GST_DEBUG_OBJECT (demux, "media type %s", media_type);
-
- caps = gst_caps_new_simple (media_type, "style", G_TYPE_STRING, style, NULL);
- gst_buffer_set_caps (buf, caps);
- gst_caps_unref (caps);
- g_free (media_type);
-
- GST_DEBUG_OBJECT (demux, "adding private tag; size %d, caps %" GST_PTR_FORMAT,
- GST_BUFFER_SIZE (buf), caps);
-
- gst_tag_list_add (demux->tag_list, GST_TAG_MERGE_APPEND,
- GST_QT_DEMUX_PRIVATE_TAG, buf, NULL);
- gst_buffer_unref (buf);
-}
-
-static void
-qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
-{
- GNode *meta;
- GNode *ilst;
- GNode *node;
- gint i;
-
- meta = qtdemux_tree_get_child_by_type (udta, FOURCC_meta);
- if (meta != NULL) {
- ilst = qtdemux_tree_get_child_by_type (meta, FOURCC_ilst);
- if (ilst == NULL) {
- GST_LOG_OBJECT (qtdemux, "no ilst");
- return;
- }
- } else {
- ilst = udta;
- GST_LOG_OBJECT (qtdemux, "no meta so using udta itself");
- }
-
- GST_DEBUG_OBJECT (qtdemux, "new tag list");
- qtdemux->tag_list = gst_tag_list_new ();
-
- for (i = 0; i < G_N_ELEMENTS (add_funcs); ++i) {
- node = qtdemux_tree_get_child_by_type (ilst, add_funcs[i].fourcc);
- if (node) {
- add_funcs[i].func (qtdemux, add_funcs[i].gst_tag,
- add_funcs[i].gst_tag_bis, node);
- g_node_destroy (node);
- }
- }
-
- /* parsed nodes have been removed, pass along remainder as blob */
- g_node_children_foreach (ilst, G_TRAVERSE_ALL,
- (GNodeForeachFunc) qtdemux_tag_add_blob, qtdemux);
-
-}
-
-typedef struct
-{
- GstStructure *structure; /* helper for sort function */
- gchar *location;
- guint min_req_bitrate;
- guint min_req_qt_version;
-} GstQtReference;
-
-static gint
-qtdemux_redirects_sort_func (gconstpointer a, gconstpointer b)
-{
- GstQtReference *ref_a = (GstQtReference *) a;
- GstQtReference *ref_b = (GstQtReference *) b;
-
- if (ref_b->min_req_qt_version != ref_a->min_req_qt_version)
- return ref_b->min_req_qt_version - ref_a->min_req_qt_version;
-
- /* known bitrates go before unknown; higher bitrates go first */
- return ref_b->min_req_bitrate - ref_a->min_req_bitrate;
-}
-
-/* sort the redirects and post a message for the application.
- */
-static void
-qtdemux_process_redirects (GstQTDemux * qtdemux, GList * references)
-{
- GstQtReference *best;
- GstStructure *s;
- GstMessage *msg;
- GValue list_val = { 0, };
- GList *l;
-
- g_assert (references != NULL);
-
- references = g_list_sort (references, qtdemux_redirects_sort_func);
-
- best = (GstQtReference *) references->data;
-
- g_value_init (&list_val, GST_TYPE_LIST);
-
- for (l = references; l != NULL; l = l->next) {
- GstQtReference *ref = (GstQtReference *) l->data;
- GValue struct_val = { 0, };
-
- ref->structure = gst_structure_new ("redirect",
- "new-location", G_TYPE_STRING, ref->location, NULL);
-
- if (ref->min_req_bitrate > 0) {
- gst_structure_set (ref->structure, "minimum-bitrate", G_TYPE_INT,
- ref->min_req_bitrate, NULL);
- }
-
- g_value_init (&struct_val, GST_TYPE_STRUCTURE);
- g_value_set_boxed (&struct_val, ref->structure);
- gst_value_list_append_value (&list_val, &struct_val);
- g_value_unset (&struct_val);
- /* don't free anything here yet, since we need best->structure below */
- }
-
- g_assert (best != NULL);
- s = gst_structure_copy (best->structure);
-
- if (g_list_length (references) > 1) {
- gst_structure_set_value (s, "locations", &list_val);
- }
-
- g_value_unset (&list_val);
-
- for (l = references; l != NULL; l = l->next) {
- GstQtReference *ref = (GstQtReference *) l->data;
-
- gst_structure_free (ref->structure);
- g_free (ref->location);
- g_free (ref);
- }
- g_list_free (references);
-
- GST_INFO_OBJECT (qtdemux, "posting redirect message: %" GST_PTR_FORMAT, s);
- msg = gst_message_new_element (GST_OBJECT_CAST (qtdemux), s);
- gst_element_post_message (GST_ELEMENT_CAST (qtdemux), msg);
-}
-
-/* look for redirect nodes, collect all redirect information and
- * process it.
- */
-static gboolean
-qtdemux_parse_redirects (GstQTDemux * qtdemux)
-{
- GNode *rmra, *rmda, *rdrf;
-
- rmra = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_rmra);
- if (rmra) {
- GList *redirects = NULL;
-
- rmda = qtdemux_tree_get_child_by_type (rmra, FOURCC_rmda);
- while (rmda) {
- GstQtReference ref = { NULL, NULL, 0, 0 };
- GNode *rmdr, *rmvc;
-
- if ((rmdr = qtdemux_tree_get_child_by_type (rmda, FOURCC_rmdr))) {
- ref.min_req_bitrate = QT_UINT32 ((guint8 *) rmdr->data + 12);
- GST_LOG_OBJECT (qtdemux, "data rate atom, required bitrate = %u",
- ref.min_req_bitrate);
- }
-
- if ((rmvc = qtdemux_tree_get_child_by_type (rmda, FOURCC_rmvc))) {
- guint32 package = QT_FOURCC ((guint8 *) rmvc->data + 12);
- guint version = QT_UINT32 ((guint8 *) rmvc->data + 16);
-
-#ifndef GST_DISABLE_GST_DEBUG
- guint bitmask = QT_UINT32 ((guint8 *) rmvc->data + 20);
-#endif
- guint check_type = QT_UINT16 ((guint8 *) rmvc->data + 24);
-
- GST_LOG_OBJECT (qtdemux,
- "version check atom [%" GST_FOURCC_FORMAT "], version=0x%08x"
- ", mask=%08x, check_type=%u", GST_FOURCC_ARGS (package), version,
- bitmask, check_type);
- if (package == FOURCC_qtim && check_type == 0) {
- ref.min_req_qt_version = version;
- }
- }
-
- rdrf = qtdemux_tree_get_child_by_type (rmda, FOURCC_rdrf);
- if (rdrf) {
- guint32 ref_type;
- guint8 *ref_data;
-
- ref_type = QT_FOURCC ((guint8 *) rdrf->data + 12);
- ref_data = (guint8 *) rdrf->data + 20;
- if (ref_type == FOURCC_alis) {
- guint record_len, record_version, fn_len;
-
- /* MacOSX alias record, google for alias-layout.txt */
- record_len = QT_UINT16 (ref_data + 4);
- record_version = QT_UINT16 (ref_data + 4 + 2);
- fn_len = QT_UINT8 (ref_data + 50);
- if (record_len > 50 && record_version == 2 && fn_len > 0) {
- ref.location = g_strndup ((gchar *) ref_data + 51, fn_len);
- }
- } else if (ref_type == FOURCC_url_) {
- ref.location = g_strdup ((gchar *) ref_data);
- } else {
- GST_DEBUG_OBJECT (qtdemux,
- "unknown rdrf reference type %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (ref_type));
- }
- if (ref.location != NULL) {
- GST_INFO_OBJECT (qtdemux, "New location: %s", ref.location);
- redirects = g_list_prepend (redirects, g_memdup (&ref, sizeof (ref)));
- } else {
- GST_WARNING_OBJECT (qtdemux,
- "Failed to extract redirect location from rdrf atom");
- }
- }
-
- /* look for others */
- rmda = qtdemux_tree_get_sibling_by_type (rmda, FOURCC_rmda);
- }
-
- if (redirects != NULL) {
- qtdemux_process_redirects (qtdemux, redirects);
- }
- }
- return TRUE;
-}
-
-static GstTagList *
-qtdemux_add_container_format (GstQTDemux * qtdemux, GstTagList * tags)
-{
- const gchar *fmt;
-
- if (tags == NULL)
- tags = gst_tag_list_new ();
-
- if (qtdemux->major_brand == FOURCC_mjp2)
- fmt = "Motion JPEG 2000";
- else if ((qtdemux->major_brand & 0xffff) == GST_MAKE_FOURCC ('3', 'g', 0, 0))
- fmt = "3GP";
- else if (qtdemux->major_brand == FOURCC_qt__)
- fmt = "Quicktime";
- else
- fmt = "ISO MP4/M4A";
-
- GST_LOG_OBJECT (qtdemux, "mapped %" GST_FOURCC_FORMAT " to '%s'",
- GST_FOURCC_ARGS (qtdemux->major_brand), fmt);
-
- gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_CONTAINER_FORMAT,
- fmt, NULL);
-
- return tags;
-}
-
-/* we have read th complete moov node now.
- * This function parses all of the relevant info, creates the traks and
- * prepares all data structures for playback
- */
-static gboolean
-qtdemux_parse_tree (GstQTDemux * qtdemux)
-{
- GNode *mvhd;
- GNode *trak;
- GNode *udta;
- gint64 duration;
-
- mvhd = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_mvhd);
- if (mvhd == NULL) {
- GST_LOG_OBJECT (qtdemux, "No mvhd node found, looking for redirects.");
- return qtdemux_parse_redirects (qtdemux);
- }
-
- qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20);
- qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24);
-
- GST_INFO_OBJECT (qtdemux, "timescale: %u", qtdemux->timescale);
- GST_INFO_OBJECT (qtdemux, "duration: %u", qtdemux->duration);
-
- /* set duration in the segment info */
- gst_qtdemux_get_duration (qtdemux, &duration);
- gst_segment_set_duration (&qtdemux->segment, GST_FORMAT_TIME, duration);
-
- /* parse all traks */
- trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
- while (trak) {
- qtdemux_parse_trak (qtdemux, trak);
- /* iterate all siblings */
- trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak);
- }
- gst_element_no_more_pads (GST_ELEMENT_CAST (qtdemux));
-
- /* find and push tags, we do this after adding the pads so we can push the
- * tags downstream as well. */
- udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta);
- if (udta) {
- qtdemux_parse_udta (qtdemux, udta);
- } else {
- GST_LOG_OBJECT (qtdemux, "No udta node found.");
- }
-
- /* FIXME: tags must be pushed after the initial newsegment event */
- qtdemux->tag_list = qtdemux_add_container_format (qtdemux, qtdemux->tag_list);
- GST_INFO_OBJECT (qtdemux, "global tags: %" GST_PTR_FORMAT, qtdemux->tag_list);
- gst_element_found_tags (GST_ELEMENT_CAST (qtdemux), qtdemux->tag_list);
- qtdemux->tag_list = NULL;
-
- return TRUE;
-}
-
-/* taken from ffmpeg */
-static unsigned int
-get_size (guint8 * ptr, guint8 ** end)
-{
- int count = 4;
- int len = 0;
-
- while (count--) {
- int c = *ptr;
-
- ptr++;
- len = (len << 7) | (c & 0x7f);
- if (!(c & 0x80))
- break;
- }
- if (end)
- *end = ptr;
- return len;
-}
-
-/* this can change the codec originally present in @list */
-static void
-gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
- GNode * esds, GstTagList * list)
-{
- int len = QT_UINT32 (esds->data);
- guint8 *ptr = esds->data;
- guint8 *end = ptr + len;
- int tag;
- guint8 *data_ptr = NULL;
- int data_len = 0;
- guint8 object_type_id = 0;
- char *codec_name = NULL;
- GstCaps *caps = NULL;
-
- GST_MEMDUMP_OBJECT (qtdemux, "esds", ptr, len);
- ptr += 8;
- GST_DEBUG_OBJECT (qtdemux, "version/flags = %08x", QT_UINT32 (ptr));
- ptr += 4;
- while (ptr < end) {
- tag = QT_UINT8 (ptr);
- GST_DEBUG_OBJECT (qtdemux, "tag = %02x", tag);
- ptr++;
- len = get_size (ptr, &ptr);
- GST_DEBUG_OBJECT (qtdemux, "len = %d", len);
-
- switch (tag) {
- case 0x03:
- GST_DEBUG_OBJECT (qtdemux, "ID %04x", QT_UINT16 (ptr));
- GST_DEBUG_OBJECT (qtdemux, "priority %04x", QT_UINT8 (ptr + 2));
- ptr += 3;
- break;
- case 0x04:
- object_type_id = QT_UINT8 (ptr);
- GST_DEBUG_OBJECT (qtdemux, "object_type_id %02x", object_type_id);
- GST_DEBUG_OBJECT (qtdemux, "stream_type %02x", QT_UINT8 (ptr + 1));
- GST_DEBUG_OBJECT (qtdemux, "buffer_size_db %02x", QT_UINT24 (ptr + 2));
- GST_DEBUG_OBJECT (qtdemux, "max bitrate %d", QT_UINT32 (ptr + 5));
- GST_DEBUG_OBJECT (qtdemux, "avg bitrate %d", QT_UINT32 (ptr + 9));
- ptr += 13;
- break;
- case 0x05:
- GST_MEMDUMP_OBJECT (qtdemux, "data", ptr, len);
- data_ptr = ptr;
- data_len = len;
- ptr += len;
- break;
- case 0x06:
- GST_DEBUG_OBJECT (qtdemux, "data %02x", QT_UINT8 (ptr));
- ptr += 1;
- break;
- default:
- GST_ERROR_OBJECT (qtdemux, "parse error");
- break;
- }
- }
-
- /* object_type_id in the esds atom in mp4a and mp4v tells us which codec is
- * in use, and should also be used to override some other parameters for some
- * codecs. */
- switch (object_type_id) {
- case 0x20: /* MPEG-4 */
- break; /* Nothing special needed here */
- case 0x21: /* H.264 */
- codec_name = "H.264 / AVC";
- caps = gst_caps_new_simple ("video/x-h264", NULL);
- break;
- case 0x40: /* AAC (any) */
- case 0x66: /* AAC Main */
- case 0x67: /* AAC LC */
- case 0x68: /* AAC SSR */
- /* Override channels and rate based on the codec_data, as it's often
- * wrong. */
- if (data_ptr && data_len >= 2) {
- guint channels, rateindex;
- int rates[] = { 96000, 88200, 64000, 48000, 44100, 32000,
- 24000, 22050, 16000, 12000, 11025, 8000
- };
-
- channels = (data_ptr[1] & 0x7f) >> 3;
- if (channels <= 7) {
- stream->n_channels = channels;
- }
-
- rateindex = ((data_ptr[0] & 0x7) << 1) | ((data_ptr[1] & 0x80) >> 7);
- if (rateindex < sizeof (rates) / sizeof (*rates)) {
- stream->rate = rates[rateindex];
- }
- }
- break;
- case 0x60: /* MPEG-2, various profiles */
- case 0x61:
- case 0x62:
- case 0x63:
- case 0x64:
- case 0x65:
- codec_name = "MPEG-2 video";
-
- gst_caps_unref (stream->caps);
- stream->caps = gst_caps_new_simple ("video/mpeg",
- "mpegversion", G_TYPE_INT, 2,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case 0x69: /* MP3 has two different values, accept either */
- case 0x6B:
- /* change to mpeg1 layer 3 audio */
- gst_caps_set_simple (stream->caps, "layer", G_TYPE_INT, 3,
- "mpegversion", G_TYPE_INT, 1, NULL);
- codec_name = "MPEG-1 layer 3";
- break;
- case 0x6A: /* MPEG-1 */
- codec_name = "MPEG-1 video";
-
- gst_caps_unref (stream->caps);
- stream->caps = gst_caps_new_simple ("video/mpeg",
- "mpegversion", G_TYPE_INT, 1,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case 0x6C: /* MJPEG */
- caps = gst_caps_new_simple ("image/jpeg", NULL);
- codec_name = "Motion-JPEG";
- break;
- case 0x6D: /* PNG */
- caps = gst_caps_new_simple ("image/png", NULL);
- codec_name = "PNG still images";
- break;
- case 0x6E: /* JPEG2000 */
- codec_name = "JPEG-2000";
- caps = gst_caps_new_simple ("image/x-j2c", "fields", G_TYPE_INT, 1, NULL);
- break;
- case 0xA4: /* Dirac */
- codec_name = "Dirac";
- caps = gst_caps_new_simple ("video/x-dirac", NULL);
- break;
- case 0xA5: /* AC3 */
- codec_name = "AC-3 audio";
- caps = gst_caps_new_simple ("audio/x-ac3", NULL);
- break;
- case 0xE1: /* QCELP */
- /* QCELP, the codec_data is a riff tag (little endian) with
- * more info (http://ftp.3gpp2.org/TSGC/Working/2003/2003-05-SanDiego/TSG-C-2003-05-San%20Diego/WG1/SWG12/C12-20030512-006%20=%20C12-20030217-015_Draft_Baseline%20Text%20of%20FFMS_R2.doc). */
- caps = gst_caps_new_simple ("audio/qcelp", NULL);
- codec_name = "QCELP";
- break;
- default:
- break;
- }
-
- /* If we have a replacement caps, then change our caps for this stream */
- if (caps) {
- gst_caps_unref (stream->caps);
- stream->caps = caps;
- }
-
- if (codec_name && list)
- gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
- GST_TAG_AUDIO_CODEC, codec_name, NULL);
-
- /* Add the codec_data attribute to caps, if we have it */
- if (data_ptr) {
- GstBuffer *buffer;
-
- buffer = gst_buffer_new_and_alloc (data_len);
- memcpy (GST_BUFFER_DATA (buffer), data_ptr, data_len);
-
- GST_DEBUG_OBJECT (qtdemux, "setting codec_data from esds");
- GST_MEMDUMP_OBJECT (qtdemux, "codec_data from esds", data_ptr, data_len);
-
- gst_caps_set_simple (stream->caps, "codec_data", GST_TYPE_BUFFER,
- buffer, NULL);
- gst_buffer_unref (buffer);
- }
-
-}
-
-#define _codec(name) \
- do { \
- if (codec_name) { \
- *codec_name = g_strdup (name); \
- } \
- } while (0)
-
-static GstCaps *
-qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
- guint32 fourcc, const guint8 * stsd_data, gchar ** codec_name)
-{
- GstCaps *caps;
- const GstStructure *s;
- const gchar *name;
-
- switch (fourcc) {
- case GST_MAKE_FOURCC ('p', 'n', 'g', ' '):
- _codec ("PNG still images");
- caps = gst_caps_new_simple ("image/png", NULL);
- break;
- case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'):
- _codec ("JPEG still images");
- caps = gst_caps_new_simple ("image/jpeg", NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'j', 'p', 'a'):
- case GST_MAKE_FOURCC ('A', 'V', 'D', 'J'):
- case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'):
- _codec ("Motion-JPEG");
- caps = gst_caps_new_simple ("image/jpeg", NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'j', 'p', 'b'):
- _codec ("Motion-JPEG format B");
- caps = gst_caps_new_simple ("video/x-mjpeg-b", NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'j', 'p', '2'):
- _codec ("JPEG-2000");
- /* override to what it should be according to spec, avoid palette_data */
- stream->bits_per_sample = 24;
- caps = gst_caps_new_simple ("image/x-j2c", "fields", G_TYPE_INT, 1, NULL);
- break;
- case GST_MAKE_FOURCC ('S', 'V', 'Q', '3'):
- _codec ("Sorensen video v.3");
- caps = gst_caps_new_simple ("video/x-svq",
- "svqversion", G_TYPE_INT, 3, NULL);
- break;
- case GST_MAKE_FOURCC ('s', 'v', 'q', 'i'):
- case GST_MAKE_FOURCC ('S', 'V', 'Q', '1'):
- _codec ("Sorensen video v.1");
- caps = gst_caps_new_simple ("video/x-svq",
- "svqversion", G_TYPE_INT, 1, NULL);
- break;
- case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
- {
- guint16 bps;
-
- _codec ("Raw RGB video");
- bps = QT_UINT16 (stsd_data + 98);
- /* set common stuff */
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "depth", G_TYPE_INT, bps,
- NULL);
-
- switch (bps) {
- case 15:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0x7c00,
- "green_mask", G_TYPE_INT, 0x03e0,
- "blue_mask", G_TYPE_INT, 0x001f, NULL);
- break;
- case 16:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0xf800,
- "green_mask", G_TYPE_INT, 0x07e0,
- "blue_mask", G_TYPE_INT, 0x001f, NULL);
- break;
- case 24:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 24,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0xff0000,
- "green_mask", G_TYPE_INT, 0x00ff00,
- "blue_mask", G_TYPE_INT, 0x0000ff, NULL);
- break;
- case 32:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "alpha_mask", G_TYPE_INT, 0xff000000,
- "red_mask", G_TYPE_INT, 0x00ff0000,
- "green_mask", G_TYPE_INT, 0x0000ff00,
- "blue_mask", G_TYPE_INT, 0x000000ff, NULL);
- break;
- default:
- /* unknown */
- break;
- }
- break;
- }
- case GST_MAKE_FOURCC ('y', 'v', '1', '2'):
- _codec ("Raw planar YUV 4:2:0");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
- NULL);
- break;
- case GST_MAKE_FOURCC ('y', 'u', 'v', '2'):
- case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'):
- _codec ("Raw packed YUV 4:2:2");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
- NULL);
- break;
- case GST_MAKE_FOURCC ('2', 'v', 'u', 'y'):
- _codec ("Raw packed YUV 4:2:0");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
- NULL);
- break;
- case GST_MAKE_FOURCC ('v', '2', '1', '0'):
- _codec ("Raw packed YUV 10-bit 4:2:2");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('v', '2', '1', '0'),
- NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'p', 'e', 'g'):
- case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
- _codec ("MPEG-1 video");
- caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 1,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('h', 'd', 'v', '1'): // HDV 720p30
- case GST_MAKE_FOURCC ('h', 'd', 'v', '2'): // HDV 1080i60
- case GST_MAKE_FOURCC ('h', 'd', 'v', '3'): // HDV 1080i50
- case GST_MAKE_FOURCC ('h', 'd', 'v', '5'): // HDV 720p25
- case GST_MAKE_FOURCC ('h', 'd', 'v', '6'): // HDV 1080i60
- case GST_MAKE_FOURCC ('m', 'x', '5', 'n'): // MPEG2 IMX NTSC 525/60 50mb/s produced by FCP
- case GST_MAKE_FOURCC ('m', 'x', '5', 'p'): // MPEG2 IMX PAL 625/60 50mb/s produced by FCP
- case GST_MAKE_FOURCC ('m', 'x', '4', 'n'): // MPEG2 IMX NTSC 525/60 40mb/s produced by FCP
- case GST_MAKE_FOURCC ('m', 'x', '4', 'p'): // MPEG2 IMX PAL 625/60 40mb/s produced by FCP
- case GST_MAKE_FOURCC ('m', 'x', '3', 'n'): // MPEG2 IMX NTSC 525/60 30mb/s produced by FCP
- case GST_MAKE_FOURCC ('m', 'x', '3', 'p'): // MPEG2 IMX PAL 625/50 30mb/s produced by FCP
- case GST_MAKE_FOURCC ('x', 'd', 'v', '2'): // XDCAM HD 1080i60
- case GST_MAKE_FOURCC ('A', 'V', 'm', 'p'): // AVID IMX PAL
- case GST_MAKE_FOURCC ('m', 'p', 'g', '2'): // AVID IMX PAL
- _codec ("MPEG-2 video");
- caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 2,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('g', 'i', 'f', ' '):
- _codec ("GIF still images");
- caps = gst_caps_new_simple ("image/gif", NULL);
- break;
- case GST_MAKE_FOURCC ('h', '2', '6', '3'):
- case GST_MAKE_FOURCC ('H', '2', '6', '3'):
- case GST_MAKE_FOURCC ('s', '2', '6', '3'):
- case GST_MAKE_FOURCC ('U', '2', '6', '3'):
- _codec ("H.263");
- /* ffmpeg uses the height/width props, don't know why */
- caps = gst_caps_new_simple ("video/x-h263", NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
- _codec ("MPEG-4 video");
- caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):
- case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):
- _codec ("Microsoft MPEG-4 4.3"); /* FIXME? */
- caps = gst_caps_new_simple ("video/x-msmpeg",
- "msmpegversion", G_TYPE_INT, 43, NULL);
- break;
- case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
- case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
- _codec ("3ivX video");
- caps = gst_caps_new_simple ("video/x-3ivx", NULL);
- break;
- case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
- _codec ("DivX 3");
- caps = gst_caps_new_simple ("video/x-divx",
- "divxversion", G_TYPE_INT, 3, NULL);
- break;
- case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
- case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
- _codec ("DivX 4");
- caps = gst_caps_new_simple ("video/x-divx",
- "divxversion", G_TYPE_INT, 4, NULL);
- break;
- case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
- _codec ("DivX 5");
- caps = gst_caps_new_simple ("video/x-divx",
- "divxversion", G_TYPE_INT, 5, NULL);
- break;
- case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
- case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
- _codec ("XVID MPEG-4");
- caps = gst_caps_new_simple ("video/x-xvid", NULL);
- break;
-
- case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
- case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
- caps = gst_caps_new_simple ("video/mpeg",
- "mpegversion", G_TYPE_INT, 4, NULL);
- if (codec_name)
- *codec_name = g_strdup ("FFmpeg MPEG-4");
- break;
-
- case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
- _codec ("Cinepak");
- caps = gst_caps_new_simple ("video/x-cinepak", NULL);
- break;
- case GST_MAKE_FOURCC ('q', 'd', 'r', 'w'):
- _codec ("Apple QuickDraw");
- caps = gst_caps_new_simple ("video/x-qdrw", NULL);
- break;
- case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'):
- _codec ("Apple video");
- caps = gst_caps_new_simple ("video/x-apple-video", NULL);
- break;
- case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
- _codec ("H.264 / AVC");
- caps = gst_caps_new_simple ("video/x-h264", NULL);
- break;
- case GST_MAKE_FOURCC ('r', 'l', 'e', ' '):
- _codec ("Run-length encoding");
- caps = gst_caps_new_simple ("video/x-rle",
- "layout", G_TYPE_STRING, "quicktime", NULL);
- break;
- case GST_MAKE_FOURCC ('i', 'v', '3', '2'):
- _codec ("Indeo Video 3");
- caps = gst_caps_new_simple ("video/x-indeo",
- "indeoversion", G_TYPE_INT, 3, NULL);
- break;
- case GST_MAKE_FOURCC ('I', 'V', '4', '1'):
- case GST_MAKE_FOURCC ('i', 'v', '4', '1'):
- _codec ("Intel Video 4");
- caps = gst_caps_new_simple ("video/x-indeo",
- "indeoversion", G_TYPE_INT, 4, NULL);
- break;
- case GST_MAKE_FOURCC ('d', 'v', 'c', 'p'):
- case GST_MAKE_FOURCC ('d', 'v', 'c', ' '):
- case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
- case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
- case GST_MAKE_FOURCC ('d', 'v', 'c', 's'):
- case GST_MAKE_FOURCC ('D', 'V', 'C', 'S'):
- case GST_MAKE_FOURCC ('d', 'v', '2', '5'):
- case GST_MAKE_FOURCC ('d', 'v', 'p', 'p'):
- _codec ("DV Video");
- caps = gst_caps_new_simple ("video/x-dv", "dvversion", G_TYPE_INT, 25,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('d', 'v', '5', 'n'): //DVCPRO50 NTSC
- case GST_MAKE_FOURCC ('d', 'v', '5', 'p'): //DVCPRO50 PAL
- _codec ("DVCPro50 Video");
- caps = gst_caps_new_simple ("video/x-dv", "dvversion", G_TYPE_INT, 50,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('d', 'v', 'h', '5'): //DVCPRO HD 50i produced by FCP
- case GST_MAKE_FOURCC ('d', 'v', 'h', '6'): //DVCPRO HD 60i produced by FCP
- _codec ("DVCProHD Video");
- caps = gst_caps_new_simple ("video/x-dv", "dvversion", G_TYPE_INT, 100,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('s', 'm', 'c', ' '):
- _codec ("Apple Graphics (SMC)");
- caps = gst_caps_new_simple ("video/x-smc", NULL);
- break;
- case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
- _codec ("VP3");
- caps = gst_caps_new_simple ("video/x-vp3", NULL);
- break;
- case GST_MAKE_FOURCC ('X', 'i', 'T', 'h'):
- _codec ("Theora");
- caps = gst_caps_new_simple ("video/x-theora", NULL);
- /* theora uses one byte of padding in the data stream because it does not
- * allow 0 sized packets while theora does */
- stream->padding = 1;
- break;
- case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
- _codec ("Dirac");
- caps = gst_caps_new_simple ("video/x-dirac", NULL);
- break;
- case GST_MAKE_FOURCC ('t', 'i', 'f', 'f'):
- _codec ("TIFF still images");
- caps = gst_caps_new_simple ("image/tiff", NULL);
- break;
- case GST_MAKE_FOURCC ('i', 'c', 'o', 'd'):
- _codec ("Apple Intermediate Codec");
- caps = gst_caps_from_string ("video/x-apple-intermediate-codec");
- break;
- case GST_MAKE_FOURCC ('A', 'V', 'd', 'n'):
- _codec ("AVID DNxHD");
- caps = gst_caps_from_string ("video/x-dnxhd");
- break;
- case GST_MAKE_FOURCC ('k', 'p', 'c', 'd'):
- default:
- {
- char *s;
-
- s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
- break;
- }
- }
-
- /* enable clipping for raw video streams */
- s = gst_caps_get_structure (caps, 0);
- name = gst_structure_get_name (s);
- if (g_str_has_prefix (name, "video/x-raw-")) {
- stream->need_clip = TRUE;
- }
- return caps;
-}
-
-static GstCaps *
-qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
- guint32 fourcc, const guint8 * data, int len, gchar ** codec_name)
-{
- GstCaps *caps;
- const GstStructure *s;
- const gchar *name;
- gint endian = 0;
-
- GST_DEBUG_OBJECT (qtdemux, "resolve fourcc %08x", fourcc);
-
- switch (fourcc) {
- case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):
- case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
- _codec ("Raw 8-bit PCM audio");
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 8,
- "depth", G_TYPE_INT, 8, "signed", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
- case GST_MAKE_FOURCC ('t', 'w', 'o', 's'):
- endian = G_BIG_ENDIAN;
- /* fall-through */
- case GST_MAKE_FOURCC ('s', 'o', 'w', 't'):
- {
- gchar *str;
- gint depth;
-
- if (!endian)
- endian = G_LITTLE_ENDIAN;
-
- depth = stream->bytes_per_packet * 8;
- str = g_strdup_printf ("Raw %d-bit PCM audio", depth);
- _codec (str);
- g_free (str);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, depth, "depth", G_TYPE_INT, depth,
- "endianness", G_TYPE_INT, endian,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- }
- case GST_MAKE_FOURCC ('f', 'l', '6', '4'):
- _codec ("Raw 64-bit floating-point audio");
- caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 64,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
- break;
- case GST_MAKE_FOURCC ('f', 'l', '3', '2'):
- _codec ("Raw 32-bit floating-point audio");
- caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
- break;
- case FOURCC_in24:
- _codec ("Raw 24-bit PCM audio");
- /* we assume BIG ENDIAN, an enda box will tell us to change this to little
- * endian later */
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 24,
- "depth", G_TYPE_INT, 24,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- case GST_MAKE_FOURCC ('i', 'n', '3', '2'):
- _codec ("Raw 32-bit PCM audio");
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 32,
- "depth", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
- _codec ("Mu-law audio");
- caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
- break;
- case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'):
- _codec ("A-law audio");
- caps = gst_caps_new_simple ("audio/x-alaw", NULL);
- break;
- case 0x0200736d:
- case 0x6d730002:
- _codec ("Microsoft ADPCM");
- /* Microsoft ADPCM-ACM code 2 */
- caps = gst_caps_new_simple ("audio/x-adpcm",
- "layout", G_TYPE_STRING, "microsoft", NULL);
- break;
- case 0x1100736d:
- case 0x6d730011:
- _codec ("IMA Loki SDL MJPEG ADPCM");
- /* Loki ADPCM, See #550288 for a file that only decodes
- * with the smjpeg variant of the ADPCM decoder. */
- caps = gst_caps_new_simple ("audio/x-adpcm",
- "layout", G_TYPE_STRING, "smjpeg", NULL);
- break;
- case 0x1700736d:
- case 0x6d730017:
- _codec ("DVI/Intel IMA ADPCM");
- /* FIXME DVI/Intel IMA ADPCM/ACM code 17 */
- caps = gst_caps_new_simple ("audio/x-adpcm",
- "layout", G_TYPE_STRING, "quicktime", NULL);
- break;
- case 0x5500736d:
- case 0x6d730055:
- /* MPEG layer 3, CBR only (pre QT4.1) */
- case GST_MAKE_FOURCC ('.', 'm', 'p', '3'):
- _codec ("MPEG-1 layer 3");
- /* MPEG layer 3, CBR & VBR (QT4.1 and later) */
- caps = gst_caps_new_simple ("audio/mpeg", "layer", G_TYPE_INT, 3,
- "mpegversion", G_TYPE_INT, 1, NULL);
- break;
- case 0x20736d:
- case GST_MAKE_FOURCC ('a', 'c', '-', '3'):
- _codec ("AC-3 audio");
- caps = gst_caps_new_simple ("audio/x-ac3", NULL);
- stream->sampled = TRUE;
- break;
- case GST_MAKE_FOURCC ('M', 'A', 'C', '3'):
- _codec ("MACE-3");
- caps = gst_caps_new_simple ("audio/x-mace",
- "maceversion", G_TYPE_INT, 3, NULL);
- break;
- case GST_MAKE_FOURCC ('M', 'A', 'C', '6'):
- _codec ("MACE-6");
- caps = gst_caps_new_simple ("audio/x-mace",
- "maceversion", G_TYPE_INT, 6, NULL);
- break;
- case GST_MAKE_FOURCC ('O', 'g', 'g', 'V'):
- /* ogg/vorbis */
- caps = gst_caps_new_simple ("application/ogg", NULL);
- break;
- case GST_MAKE_FOURCC ('d', 'v', 'c', 'a'):
- _codec ("DV audio");
- caps = gst_caps_new_simple ("audio/x-dv", NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
- _codec ("MPEG-4 AAC audio");
- caps = gst_caps_new_simple ("audio/mpeg",
- "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'):
- _codec ("QDesign Music");
- caps = gst_caps_new_simple ("audio/x-qdm", NULL);
- break;
- case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'):
- _codec ("QDesign Music v.2");
- /* FIXME: QDesign music version 2 (no constant) */
- if (data) {
- caps = gst_caps_new_simple ("audio/x-qdm2",
- "framesize", G_TYPE_INT, QT_UINT32 (data + 52),
- "bitrate", G_TYPE_INT, QT_UINT32 (data + 40),
- "blocksize", G_TYPE_INT, QT_UINT32 (data + 44), NULL);
- } else {
- caps = gst_caps_new_simple ("audio/x-qdm2", NULL);
- }
- break;
- case GST_MAKE_FOURCC ('a', 'g', 's', 'm'):
- _codec ("GSM audio");
- caps = gst_caps_new_simple ("audio/x-gsm", NULL);
- break;
- case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'):
- _codec ("AMR audio");
- caps = gst_caps_new_simple ("audio/AMR", NULL);
- break;
- case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'):
- _codec ("AMR-WB audio");
- caps = gst_caps_new_simple ("audio/AMR-WB", NULL);
- break;
- case GST_MAKE_FOURCC ('i', 'm', 'a', '4'):
- _codec ("Quicktime IMA ADPCM");
- caps = gst_caps_new_simple ("audio/x-adpcm",
- "layout", G_TYPE_STRING, "quicktime", NULL);
- break;
- case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'):
- _codec ("Apple lossless audio");
- caps = gst_caps_new_simple ("audio/x-alac", NULL);
- break;
- case GST_MAKE_FOURCC ('q', 't', 'v', 'r'):
- /* ? */
- case GST_MAKE_FOURCC ('Q', 'c', 'l', 'p'):
- /* QUALCOMM PureVoice */
- default:
- {
- char *s;
-
- s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
- break;
- }
- }
-
- /* enable clipping for raw audio streams */
- s = gst_caps_get_structure (caps, 0);
- name = gst_structure_get_name (s);
- if (g_str_has_prefix (name, "audio/x-raw-")) {
- stream->need_clip = TRUE;
- }
- return caps;
-}
-
-static GstCaps *
-qtdemux_subp_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
- guint32 fourcc, const guint8 * stsd_data, gchar ** codec_name)
-{
- GstCaps *caps;
-
- GST_DEBUG_OBJECT (qtdemux, "resolve fourcc %08x", fourcc);
-
- switch (fourcc) {
- case GST_MAKE_FOURCC ('m', 'p', '4', 's'):
- _codec ("DVD subtitle");
- caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
- break;
- default:
- {
- char *s;
-
- s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
- break;
- }
- }
- return caps;
-}
--- a/gst_plugins_good/gst/qtdemux/qtdemux.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_QTDEMUX_H__
-#define __GST_QTDEMUX_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-
-G_BEGIN_DECLS
-
-GST_DEBUG_CATEGORY_EXTERN (qtdemux_debug);
-#define GST_CAT_DEFAULT qtdemux_debug
-
-#define GST_TYPE_QTDEMUX \
- (gst_qtdemux_get_type())
-#define GST_QTDEMUX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_QTDEMUX,GstQTDemux))
-#define GST_QTDEMUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_QTDEMUX,GstQTDemuxClass))
-#define GST_IS_QTDEMUX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_QTDEMUX))
-#define GST_IS_QTDEMUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_QTDEMUX))
-
-#define GST_QTDEMUX_CAST(obj) ((GstQTDemux *)(obj))
-
-/* qtdemux produces these for atoms it cannot parse */
-#define GST_QT_DEMUX_PRIVATE_TAG "private-qt-tag"
-#define GST_QT_DEMUX_CLASSIFICATION_TAG "classification"
-
-#define GST_QTDEMUX_MAX_STREAMS 8
-
-typedef struct _GstQTDemux GstQTDemux;
-typedef struct _GstQTDemuxClass GstQTDemuxClass;
-typedef struct _QtDemuxStream QtDemuxStream;
-
-struct _GstQTDemux {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad;
-
- QtDemuxStream *streams[GST_QTDEMUX_MAX_STREAMS];
- gint n_streams;
- gint n_video_streams;
- gint n_audio_streams;
- gint n_subp_streams;
-
- guint major_brand;
- GNode *moov_node;
- GNode *moov_node_compressed;
-
- guint32 timescale;
- guint32 duration;
-
- gint state;
-
- gboolean pullbased;
-
- /* push based variables */
- guint neededbytes;
- guint todrop;
- GstAdapter *adapter;
- GstBuffer *mdatbuffer;
-
- /* offset of the media data (i.e.: Size of header) */
- guint64 offset;
- /* offset of the mdat atom */
- guint64 mdatoffset;
-
- GstTagList *tag_list;
-
- /* track stuff */
- guint64 last_ts;
-
- /* configured playback region */
- GstSegment segment;
- gboolean segment_running;
- GstEvent *pending_newsegment;
-};
-
-struct _GstQTDemuxClass {
- GstElementClass parent_class;
-};
-
-#ifdef __SYMBIAN32__
-IMPORT_C
-#endif
-GType gst_qtdemux_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_QTDEMUX_H__ */
--- a/gst_plugins_good/gst/qtdemux/qtdemux_dump.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,432 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "qtdemux_types.h"
-#include "qtdemux_dump.h"
-
-void
-qtdemux_dump_mvhd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s creation time: %u", depth, "", QT_UINT32 (buffer + 12));
- GST_LOG ("%*s modify time: %u", depth, "", QT_UINT32 (buffer + 16));
- GST_LOG ("%*s time scale: 1/%u sec", depth, "", QT_UINT32 (buffer + 20));
- GST_LOG ("%*s duration: %u", depth, "", QT_UINT32 (buffer + 24));
- GST_LOG ("%*s pref. rate: %g", depth, "", QT_FP32 (buffer + 28));
- GST_LOG ("%*s pref. volume: %g", depth, "", QT_FP16 (buffer + 32));
- GST_LOG ("%*s preview time: %u", depth, "", QT_UINT32 (buffer + 80));
- GST_LOG ("%*s preview dur.: %u", depth, "", QT_UINT32 (buffer + 84));
- GST_LOG ("%*s poster time: %u", depth, "", QT_UINT32 (buffer + 88));
- GST_LOG ("%*s select time: %u", depth, "", QT_UINT32 (buffer + 92));
- GST_LOG ("%*s select dur.: %u", depth, "", QT_UINT32 (buffer + 96));
- GST_LOG ("%*s current time: %u", depth, "", QT_UINT32 (buffer + 100));
- GST_LOG ("%*s next track ID: %d", depth, "", QT_UINT32 (buffer + 104));
-}
-
-void
-qtdemux_dump_tkhd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s creation time: %u", depth, "", QT_UINT32 (buffer + 12));
- GST_LOG ("%*s modify time: %u", depth, "", QT_UINT32 (buffer + 16));
- GST_LOG ("%*s track ID: %u", depth, "", QT_UINT32 (buffer + 20));
- GST_LOG ("%*s duration: %u", depth, "", QT_UINT32 (buffer + 28));
- GST_LOG ("%*s layer: %u", depth, "", QT_UINT16 (buffer + 36));
- GST_LOG ("%*s alt group: %u", depth, "", QT_UINT16 (buffer + 38));
- GST_LOG ("%*s volume: %g", depth, "", QT_FP16 (buffer + 44));
- GST_LOG ("%*s track width: %g", depth, "", QT_FP32 (buffer + 84));
- GST_LOG ("%*s track height: %g", depth, "", QT_FP32 (buffer + 88));
-
-}
-
-void
-qtdemux_dump_elst (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %u", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s track dur: %u", depth, "",
- QT_UINT32 (buffer + 16 + i * 12));
- GST_LOG ("%*s media time: %u", depth, "",
- QT_UINT32 (buffer + 20 + i * 12));
- GST_LOG ("%*s media rate: %g", depth, "",
- QT_FP32 (buffer + 24 + i * 12));
- }
-}
-
-void
-qtdemux_dump_mdhd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- guint32 version;
- guint64 duration, ctime, mtime;
- guint32 time_scale;
- guint16 language, quality;
-
- version = QT_UINT32 (buffer + 8);
- GST_LOG ("%*s version/flags: %08x", depth, "", version);
-
- if (version == 0x01000000) {
- ctime = QT_UINT64 (buffer + 12);
- mtime = QT_UINT64 (buffer + 20);
- time_scale = QT_UINT32 (buffer + 28);
- duration = QT_UINT64 (buffer + 32);
- language = QT_UINT16 (buffer + 40);
- quality = QT_UINT16 (buffer + 42);
- } else {
- ctime = QT_UINT32 (buffer + 12);
- mtime = QT_UINT32 (buffer + 16);
- time_scale = QT_UINT32 (buffer + 20);
- duration = QT_UINT32 (buffer + 24);
- language = QT_UINT16 (buffer + 28);
- quality = QT_UINT16 (buffer + 30);
- }
-
- GST_LOG ("%*s creation time: %" G_GUINT64_FORMAT, depth, "", ctime);
- GST_LOG ("%*s modify time: %" G_GUINT64_FORMAT, depth, "", mtime);
- GST_LOG ("%*s time scale: 1/%u sec", depth, "", time_scale);
- GST_LOG ("%*s duration: %" G_GUINT64_FORMAT, depth, "", duration);
- GST_LOG ("%*s language: %u", depth, "", language);
- GST_LOG ("%*s quality: %u", depth, "", quality);
-}
-
-void
-qtdemux_dump_hdlr (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + 12)));
- GST_LOG ("%*s subtype: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + 16)));
- GST_LOG ("%*s manufacturer: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + 20)));
- GST_LOG ("%*s flags: %08x", depth, "", QT_UINT32 (buffer + 24));
- GST_LOG ("%*s flags mask: %08x", depth, "", QT_UINT32 (buffer + 28));
- GST_LOG ("%*s name: %*s", depth, "",
- QT_UINT8 (buffer + 32), (char *) (buffer + 33));
-
-}
-
-void
-qtdemux_dump_vmhd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s mode/color: %08x", depth, "", QT_UINT32 (buffer + 16));
-}
-
-void
-qtdemux_dump_dref (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int n;
- int i;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %u", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s size: %u", depth, "",
- QT_UINT32 (buffer + offset));
- GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 4)));
- offset += QT_UINT32 (buffer + offset);
- }
-}
-
-void
-qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s size: %u", depth, "",
- QT_UINT32 (buffer + offset));
- GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 4)));
- GST_LOG ("%*s data reference:%d", depth, "",
- QT_UINT16 (buffer + offset + 14));
-
- GST_LOG ("%*s version/rev.: %08x", depth, "",
- QT_UINT32 (buffer + offset + 16));
- GST_LOG ("%*s vendor: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 20)));
- GST_LOG ("%*s temporal qual: %u", depth, "",
- QT_UINT32 (buffer + offset + 24));
- GST_LOG ("%*s spatial qual: %u", depth, "",
- QT_UINT32 (buffer + offset + 28));
- GST_LOG ("%*s width: %u", depth, "",
- QT_UINT16 (buffer + offset + 32));
- GST_LOG ("%*s height: %u", depth, "",
- QT_UINT16 (buffer + offset + 34));
- GST_LOG ("%*s horiz. resol: %g", depth, "",
- QT_FP32 (buffer + offset + 36));
- GST_LOG ("%*s vert. resol.: %g", depth, "",
- QT_FP32 (buffer + offset + 40));
- GST_LOG ("%*s data size: %u", depth, "",
- QT_UINT32 (buffer + offset + 44));
- GST_LOG ("%*s frame count: %u", depth, "",
- QT_UINT16 (buffer + offset + 48));
- GST_LOG ("%*s compressor: %d %d %d", depth, "",
- QT_UINT8 (buffer + offset + 49),
- QT_UINT8 (buffer + offset + 50), QT_UINT8 (buffer + offset + 51));
- //(char *) (buffer + offset + 51));
- GST_LOG ("%*s depth: %u", depth, "",
- QT_UINT16 (buffer + offset + 82));
- GST_LOG ("%*s color table ID:%u", depth, "",
- QT_UINT16 (buffer + offset + 84));
-
- offset += QT_UINT32 (buffer + offset);
- }
-}
-
-void
-qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s count: %u", depth, "",
- QT_UINT32 (buffer + offset));
- GST_LOG ("%*s duration: %u", depth, "",
- QT_UINT32 (buffer + offset + 4));
-
- offset += 8;
- }
-}
-
-void
-qtdemux_dump_stps (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s sample: %u", depth, "",
- QT_UINT32 (buffer + offset));
-
- offset += 4;
- }
-}
-
-void
-qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s sample: %u", depth, "",
- QT_UINT32 (buffer + offset));
-
- offset += 4;
- }
-}
-
-void
-qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s first chunk: %u", depth, "",
- QT_UINT32 (buffer + offset));
- GST_LOG ("%*s sample per ch: %u", depth, "",
- QT_UINT32 (buffer + offset + 4));
- GST_LOG ("%*s sample desc id:%08x", depth, "",
- QT_UINT32 (buffer + offset + 8));
-
- offset += 12;
- }
-}
-
-void
-qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- //int i;
- int n;
- int offset;
- int sample_size;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- sample_size = QT_UINT32 (buffer + 12);
- GST_LOG ("%*s sample size: %d", depth, "", sample_size);
- if (sample_size == 0) {
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 16));
- n = QT_UINT32 (buffer + 16);
- offset = 20;
-#if 0
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s sample size: %u", depth, "",
- QT_UINT32 (buffer + offset));
-
- offset += 4;
- }
-#endif
- }
-}
-
-void
-qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- n = QT_UINT32 (buffer + 12);
- GST_LOG ("%*s n entries: %d", depth, "", n);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s chunk offset: %d", depth, "",
- QT_UINT32 (buffer + offset));
-
- offset += 4;
- }
-}
-
-void
-qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- n = QT_UINT32 (buffer + 12);
- GST_LOG ("%*s n entries: %d", depth, "", n);
- offset = 16;
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s sample count :%8d offset: %8d",
- depth, "", QT_UINT32 (buffer + offset),
- QT_UINT32 (buffer + offset + 4));
-
- offset += 8;
- }
-}
-
-void
-qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- //int i;
- int n;
- int offset;
-
- GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
- GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
- n = QT_UINT32 (buffer + 12);
- offset = 16;
-#if 0
- for (i = 0; i < n; i++) {
- GST_LOG ("%*s chunk offset: %" G_GUINT64_FORMAT, depth, "",
- QTDEMUX_GUINT64_GET (buffer + offset));
-
- offset += 8;
- }
-#endif
-}
-
-void
-qtdemux_dump_dcom (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s compression type: %" GST_FOURCC_FORMAT, depth, "",
- GST_FOURCC_ARGS (QT_FOURCC (buffer + 8)));
-}
-
-void
-qtdemux_dump_cmvd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- GST_LOG ("%*s length: %d", depth, "", QT_UINT32 (buffer + 8));
-}
-
-void
-qtdemux_dump_unknown (GstQTDemux * qtdemux, guint8 * buffer, int depth)
-{
- int len;
-
- GST_LOG ("%*s length: %d", depth, "", QT_UINT32 (buffer + 0));
-
- len = QT_UINT32 (buffer + 0);
- GST_MEMDUMP_OBJECT (qtdemux, "unknown atom data", buffer, len);
-}
-
-static gboolean
-qtdemux_node_dump_foreach (GNode * node, gpointer qtdemux)
-{
- guint8 *buffer = (guint8 *) node->data;
- guint32 node_length;
- guint32 fourcc;
- const QtNodeType *type;
- int depth;
-
- node_length = GST_READ_UINT32_BE (buffer);
- fourcc = GST_READ_UINT32_LE (buffer + 4);
-
- type = qtdemux_type_get (fourcc);
-
- depth = (g_node_depth (node) - 1) * 2;
- GST_LOG ("%*s'%" GST_FOURCC_FORMAT "', [%d], %s",
- depth, "", GST_FOURCC_ARGS (fourcc), node_length, type->name);
-
- if (type->dump)
- type->dump (GST_QTDEMUX_CAST (qtdemux), buffer, depth);
-
- return FALSE;
-}
-
-void
-qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node)
-{
- if (__gst_debug_min < GST_LEVEL_LOG)
- return;
-
- g_node_traverse (qtdemux->moov_node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- qtdemux_node_dump_foreach, qtdemux);
-}
--- a/gst_plugins_good/gst/qtdemux/qtdemux_dump.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_QTDEMUX_DUMP_H__
-#define __GST_QTDEMUX_DUMP_H__
-
-#include <gst/gst.h>
-#include <qtdemux.h>
-
-G_BEGIN_DECLS
-
-void qtdemux_dump_mvhd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_tkhd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_elst (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_mdhd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_hdlr (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_vmhd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_dref (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stps (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_dcom (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_cmvd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-void qtdemux_dump_unknown (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-
-void qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node);
-
-G_END_DECLS
-
-#endif /* __GST_QTDEMUX_DUMP_H__ */
--- a/gst_plugins_good/gst/qtdemux/qtdemux_fourcc.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_QTDEMUX_FOURCC_H__
-#define __GST_QTDEMUX_FOURCC_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define FOURCC_ftyp GST_MAKE_FOURCC('f','t','y','p')
-#define FOURCC_qt__ GST_MAKE_FOURCC('q','t',' ',' ')
-#define FOURCC_moov GST_MAKE_FOURCC('m','o','o','v')
-#define FOURCC_mvhd GST_MAKE_FOURCC('m','v','h','d')
-#define FOURCC_clip GST_MAKE_FOURCC('c','l','i','p')
-#define FOURCC_trak GST_MAKE_FOURCC('t','r','a','k')
-#define FOURCC_udta GST_MAKE_FOURCC('u','d','t','a')
-#define FOURCC_ctab GST_MAKE_FOURCC('c','t','a','b')
-#define FOURCC_tkhd GST_MAKE_FOURCC('t','k','h','d')
-#define FOURCC_crgn GST_MAKE_FOURCC('c','r','g','n')
-#define FOURCC_matt GST_MAKE_FOURCC('m','a','t','t')
-#define FOURCC_kmat GST_MAKE_FOURCC('k','m','a','t')
-#define FOURCC_edts GST_MAKE_FOURCC('e','d','t','s')
-#define FOURCC_elst GST_MAKE_FOURCC('e','l','s','t')
-#define FOURCC_load GST_MAKE_FOURCC('l','o','a','d')
-#define FOURCC_tref GST_MAKE_FOURCC('t','r','e','f')
-#define FOURCC_imap GST_MAKE_FOURCC('i','m','a','p')
-#define FOURCC___in GST_MAKE_FOURCC(' ',' ','i','n')
-#define FOURCC___ty GST_MAKE_FOURCC(' ',' ','t','y')
-#define FOURCC_mdia GST_MAKE_FOURCC('m','d','i','a')
-#define FOURCC_mdhd GST_MAKE_FOURCC('m','d','h','d')
-#define FOURCC_hdlr GST_MAKE_FOURCC('h','d','l','r')
-#define FOURCC_minf GST_MAKE_FOURCC('m','i','n','f')
-#define FOURCC_vmhd GST_MAKE_FOURCC('v','m','h','d')
-#define FOURCC_smhd GST_MAKE_FOURCC('s','m','h','d')
-#define FOURCC_gmhd GST_MAKE_FOURCC('g','m','h','d')
-#define FOURCC_gmin GST_MAKE_FOURCC('g','m','i','n')
-#define FOURCC_dinf GST_MAKE_FOURCC('d','i','n','f')
-#define FOURCC_dref GST_MAKE_FOURCC('d','r','e','f')
-#define FOURCC_stbl GST_MAKE_FOURCC('s','t','b','l')
-#define FOURCC_stsd GST_MAKE_FOURCC('s','t','s','d')
-#define FOURCC_stts GST_MAKE_FOURCC('s','t','t','s')
-#define FOURCC_stss GST_MAKE_FOURCC('s','t','s','s')
-#define FOURCC_stps GST_MAKE_FOURCC('s','t','p','s')
-#define FOURCC_stsc GST_MAKE_FOURCC('s','t','s','c')
-#define FOURCC_stsz GST_MAKE_FOURCC('s','t','s','z')
-#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o')
-#define FOURCC_vide GST_MAKE_FOURCC('v','i','d','e')
-#define FOURCC_soun GST_MAKE_FOURCC('s','o','u','n')
-#define FOURCC_subp GST_MAKE_FOURCC('s','u','b','p')
-#define FOURCC_strm GST_MAKE_FOURCC('s','t','r','m')
-#define FOURCC_rtsp GST_MAKE_FOURCC('r','t','s','p')
-#define FOURCC_co64 GST_MAKE_FOURCC('c','o','6','4')
-#define FOURCC_cmov GST_MAKE_FOURCC('c','m','o','v')
-#define FOURCC_dcom GST_MAKE_FOURCC('d','c','o','m')
-#define FOURCC_cmvd GST_MAKE_FOURCC('c','m','v','d')
-#define FOURCC_hint GST_MAKE_FOURCC('h','i','n','t')
-#define FOURCC_mp4a GST_MAKE_FOURCC('m','p','4','a')
-#define FOURCC_mp4v GST_MAKE_FOURCC('m','p','4','v')
-#define FOURCC_wave GST_MAKE_FOURCC('w','a','v','e')
-#define FOURCC_appl GST_MAKE_FOURCC('a','p','p','l')
-#define FOURCC_esds GST_MAKE_FOURCC('e','s','d','s')
-#define FOURCC_pasp GST_MAKE_FOURCC('p','a','s','p')
-#define FOURCC_hnti GST_MAKE_FOURCC('h','n','t','i')
-#define FOURCC_rtp_ GST_MAKE_FOURCC('r','t','p',' ')
-#define FOURCC_sdp_ GST_MAKE_FOURCC('s','d','p',' ')
-#define FOURCC_meta GST_MAKE_FOURCC('m','e','t','a')
-#define FOURCC_ilst GST_MAKE_FOURCC('i','l','s','t')
-#define FOURCC__nam GST_MAKE_FOURCC(0xa9,'n','a','m')
-#define FOURCC__cmt GST_MAKE_FOURCC(0xa9,'c','m','t')
-#define FOURCC__des GST_MAKE_FOURCC(0xa9,'d','e','s')
-#define FOURCC__cpy GST_MAKE_FOURCC(0xa9,'c','p','y')
-#define FOURCC__ART GST_MAKE_FOURCC(0xa9,'A','R','T')
-#define FOURCC__wrt GST_MAKE_FOURCC(0xa9,'w','r','t')
-#define FOURCC__grp GST_MAKE_FOURCC(0xa9,'g','r','p')
-#define FOURCC__alb GST_MAKE_FOURCC(0xa9,'a','l','b')
-#define FOURCC__day GST_MAKE_FOURCC(0xa9,'d','a','y')
-#define FOURCC__req GST_MAKE_FOURCC(0xa9,'r','e','q')
-#define FOURCC__enc GST_MAKE_FOURCC(0xa9,'e','n','c')
-#define FOURCC__inf GST_MAKE_FOURCC(0xa9,'i','n','f')
-#define FOURCC_cprt GST_MAKE_FOURCC('c','p','r','t')
-#define FOURCC_gnre GST_MAKE_FOURCC('g','n','r','e')
-#define FOURCC_disc GST_MAKE_FOURCC('d','i','s','c')
-#define FOURCC_disk GST_MAKE_FOURCC('d','i','s','k')
-#define FOURCC_trkn GST_MAKE_FOURCC('t','r','k','n')
-#define FOURCC_cpil GST_MAKE_FOURCC('c','p','i','l')
-#define FOURCC_tmpo GST_MAKE_FOURCC('t','m','p','o')
-#define FOURCC_covr GST_MAKE_FOURCC('c','o','v','r')
-#define FOURCC__too GST_MAKE_FOURCC(0xa9,'t','o','o')
-#define FOURCC_____ GST_MAKE_FOURCC('-','-','-','-')
-#define FOURCC_free GST_MAKE_FOURCC('f','r','e','e')
-#define FOURCC_data GST_MAKE_FOURCC('d','a','t','a')
-#define FOURCC_SVQ3 GST_MAKE_FOURCC('S','V','Q','3')
-#define FOURCC_rmra GST_MAKE_FOURCC('r','m','r','a')
-#define FOURCC_rmda GST_MAKE_FOURCC('r','m','d','a')
-#define FOURCC_rdrf GST_MAKE_FOURCC('r','d','r','f')
-#define FOURCC__gen GST_MAKE_FOURCC(0xa9, 'g', 'e', 'n')
-#define FOURCC_rmdr GST_MAKE_FOURCC('r','m','d','r')
-#define FOURCC_rmvc GST_MAKE_FOURCC('r','m','v','c')
-#define FOURCC_qtim GST_MAKE_FOURCC('q','t','i','m')
-#define FOURCC_drms GST_MAKE_FOURCC('d','r','m','s')
-#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1')
-#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C')
-#define FOURCC_VP31 GST_MAKE_FOURCC('V','P','3','1')
-#define FOURCC_rle_ GST_MAKE_FOURCC('r','l','e',' ')
-#define FOURCC_MAC6 GST_MAKE_FOURCC('M','A','C','6')
-#define FOURCC_MAC3 GST_MAKE_FOURCC('M','A','C','3')
-#define FOURCC_ima4 GST_MAKE_FOURCC('i','m','a','4')
-#define FOURCC_ulaw GST_MAKE_FOURCC('u','l','a','w')
-#define FOURCC_alaw GST_MAKE_FOURCC('a','l','a','w')
-#define FOURCC_twos GST_MAKE_FOURCC('t','w','o','s')
-#define FOURCC_sowt GST_MAKE_FOURCC('s','o','w','t')
-#define FOURCC_raw_ GST_MAKE_FOURCC('r','a','w',' ')
-#define FOURCC_in24 GST_MAKE_FOURCC('i','n','2','4')
-#define FOURCC_enda GST_MAKE_FOURCC('e','n','d','a')
-#define FOURCC_QDM2 GST_MAKE_FOURCC('Q','D','M','2')
-#define FOURCC_alac GST_MAKE_FOURCC('a','l','a','c')
-#define FOURCC_samr GST_MAKE_FOURCC('s','a','m','r')
-#define FOURCC_sawb GST_MAKE_FOURCC('s','a','w','b')
-#define FOURCC_mdat GST_MAKE_FOURCC('m','d','a','t')
-#define FOURCC_wide GST_MAKE_FOURCC('w','i','d','e')
-#define FOURCC_PICT GST_MAKE_FOURCC('P','I','C','T')
-#define FOURCC_pnot GST_MAKE_FOURCC('p','n','o','t')
-#define FOURCC_zlib GST_MAKE_FOURCC('z','l','i','b')
-#define FOURCC_alis GST_MAKE_FOURCC('a','l','i','s')
-#define FOURCC_url_ GST_MAKE_FOURCC('u','r','l',' ')
-#define FOURCC_frma GST_MAKE_FOURCC('f','r','m','a')
-#define FOURCC_ctts GST_MAKE_FOURCC('c','t','t','s')
-#define FOURCC_keyw GST_MAKE_FOURCC('k','e','y','w')
-#define FOURCC_kywd GST_MAKE_FOURCC('k','y','w','d')
-#define FOURCC_agsm GST_MAKE_FOURCC('a','g','s','m')
-
-/* 3gpp asset meta data fourcc */
-#define FOURCC_titl GST_MAKE_FOURCC('t','i','t','l')
-#define FOURCC_dscp GST_MAKE_FOURCC('d','s','c','p')
-#define FOURCC_perf GST_MAKE_FOURCC('p','e','r','f')
-#define FOURCC_auth GST_MAKE_FOURCC('a','u','t','h')
-#define FOURCC_rtng GST_MAKE_FOURCC('r','t','n','g')
-#define FOURCC_clsf GST_MAKE_FOURCC('c','l','s','f')
-#define FOURCC_loci GST_MAKE_FOURCC('l','o','c','i')
-#define FOURCC_albm GST_MAKE_FOURCC('a','l','b','m')
-#define FOURCC_yrrc GST_MAKE_FOURCC('y','r','r','c')
-
-/* ISO Motion JPEG 2000 fourcc */
-#define FOURCC_mjp2 GST_MAKE_FOURCC('m','j','p','2')
-#define FOURCC_jp2h GST_MAKE_FOURCC('j','p','2','h')
-#define FOURCC_colr GST_MAKE_FOURCC('c','o','l','r')
-#define FOURCC_fiel GST_MAKE_FOURCC('f','i','e','l')
-#define FOURCC_jp2x GST_MAKE_FOURCC('j','p','2','x')
-/* some buggy hardware's notion of mdhd */
-#define FOURCC_mhdr GST_MAKE_FOURCC('m','h','d','r')
-
-/* Xiph fourcc */
-#define FOURCC_XiTh GST_MAKE_FOURCC('X','i','T','h')
-#define FOURCC_XdxT GST_MAKE_FOURCC('X','d','x','T')
-#define FOURCC_tCtH GST_MAKE_FOURCC('t','C','t','H')
-#define FOURCC_tCt_ GST_MAKE_FOURCC('t','C','t','#')
-#define FOURCC_tCtC GST_MAKE_FOURCC('t','C','t','C')
-
-G_END_DECLS
-
-#endif /* __GST_QTDEMUX_FOURCC_H__ */
--- a/gst_plugins_good/gst/qtdemux/qtdemux_types.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "qtdemux_types.h"
-#include "qtdemux_dump.h"
-#include "qtdemux_fourcc.h"
-
-static const QtNodeType qt_node_types[] = {
- {FOURCC_moov, "movie", QT_FLAG_CONTAINER,},
- {FOURCC_mvhd, "movie header", 0,
- qtdemux_dump_mvhd},
- {FOURCC_clip, "clipping", QT_FLAG_CONTAINER,},
- {FOURCC_trak, "track", QT_FLAG_CONTAINER,},
- {FOURCC_udta, "user data", QT_FLAG_CONTAINER,}, /* special container */
- {FOURCC_ctab, "color table", 0,},
- {FOURCC_tkhd, "track header", 0,
- qtdemux_dump_tkhd},
- {FOURCC_crgn, "clipping region", 0,},
- {FOURCC_matt, "track matte", QT_FLAG_CONTAINER,},
- {FOURCC_kmat, "compressed matte", 0,},
- {FOURCC_edts, "edit", QT_FLAG_CONTAINER,},
- {FOURCC_elst, "edit list", 0,
- qtdemux_dump_elst},
- {FOURCC_load, "track load settings", 0,},
- {FOURCC_tref, "track reference", QT_FLAG_CONTAINER,},
- {FOURCC_imap, "track input map", QT_FLAG_CONTAINER,},
- {FOURCC___in, "track input", 0,}, /* special container */
- {FOURCC___ty, "input type", 0,},
- {FOURCC_mdia, "media", QT_FLAG_CONTAINER},
- {FOURCC_mdhd, "media header", 0,
- qtdemux_dump_mdhd},
- {FOURCC_hdlr, "handler reference", 0,
- qtdemux_dump_hdlr},
- {FOURCC_minf, "media information", QT_FLAG_CONTAINER},
- {FOURCC_vmhd, "video media information", 0,
- qtdemux_dump_vmhd},
- {FOURCC_smhd, "sound media information", 0},
- {FOURCC_gmhd, "base media information header", 0},
- {FOURCC_gmin, "base media info", 0},
- {FOURCC_dinf, "data information", QT_FLAG_CONTAINER},
- {FOURCC_dref, "data reference", 0,
- qtdemux_dump_dref},
- {FOURCC_stbl, "sample table", QT_FLAG_CONTAINER},
- {FOURCC_stsd, "sample description", 0,
- qtdemux_dump_stsd},
- {FOURCC_stts, "time-to-sample", 0,
- qtdemux_dump_stts},
- {FOURCC_stps, "partial sync sample", 0,
- qtdemux_dump_stps},
- {FOURCC_stss, "sync sample", 0,
- qtdemux_dump_stss},
- {FOURCC_stsc, "sample-to-chunk", 0,
- qtdemux_dump_stsc},
- {FOURCC_stsz, "sample size", 0,
- qtdemux_dump_stsz},
- {FOURCC_stco, "chunk offset", 0,
- qtdemux_dump_stco},
- {FOURCC_co64, "64-bit chunk offset", 0,
- qtdemux_dump_co64},
- {FOURCC_vide, "video media", 0},
- {FOURCC_cmov, "compressed movie", QT_FLAG_CONTAINER},
- {FOURCC_dcom, "compressed data", 0, qtdemux_dump_dcom},
- {FOURCC_cmvd, "compressed movie data", 0, qtdemux_dump_cmvd},
- {FOURCC_hint, "hint", 0,},
- {FOURCC_mp4a, "mp4a", 0,},
- {FOURCC_mp4v, "mp4v", 0,},
- {FOURCC_mjp2, "mjp2", 0,},
- {FOURCC_mhdr, "mhdr", QT_FLAG_CONTAINER,},
- {FOURCC_jp2h, "jp2h", QT_FLAG_CONTAINER,},
- {FOURCC_colr, "colr", 0,},
- {FOURCC_fiel, "fiel", 0,},
- {FOURCC_jp2x, "jp2x", 0,},
- {FOURCC_wave, "wave", QT_FLAG_CONTAINER},
- {FOURCC_appl, "appl", QT_FLAG_CONTAINER},
- {FOURCC_esds, "esds", 0},
- {FOURCC_hnti, "hnti", QT_FLAG_CONTAINER},
- {FOURCC_rtp_, "rtp ", 0, qtdemux_dump_unknown},
- {FOURCC_sdp_, "sdp ", 0, qtdemux_dump_unknown},
- {FOURCC_meta, "meta", 0, qtdemux_dump_unknown},
- {FOURCC_ilst, "ilst", QT_FLAG_CONTAINER,},
- {FOURCC__nam, "Name", QT_FLAG_CONTAINER,},
- {FOURCC_titl, "Title", QT_FLAG_CONTAINER,},
- {FOURCC__ART, "Artist", QT_FLAG_CONTAINER,},
- {FOURCC_auth, "Author", QT_FLAG_CONTAINER,},
- {FOURCC_perf, "Performer", QT_FLAG_CONTAINER,},
- {FOURCC__wrt, "Writer", QT_FLAG_CONTAINER,},
- {FOURCC__grp, "Group", QT_FLAG_CONTAINER,},
- {FOURCC__alb, "Album", QT_FLAG_CONTAINER,},
- {FOURCC_albm, "Album", QT_FLAG_CONTAINER,},
- {FOURCC__day, "Date", QT_FLAG_CONTAINER,},
- {FOURCC__cpy, "Copyright", QT_FLAG_CONTAINER,},
- {FOURCC__cmt, "Comment", QT_FLAG_CONTAINER,},
- {FOURCC__des, "Description", QT_FLAG_CONTAINER,},
- {FOURCC_dscp, "Description", QT_FLAG_CONTAINER,},
- {FOURCC__req, "Requirement", QT_FLAG_CONTAINER,},
- {FOURCC__enc, "Encoder", QT_FLAG_CONTAINER,},
- {FOURCC_gnre, "Genre", QT_FLAG_CONTAINER,},
- {FOURCC_trkn, "Track Number", QT_FLAG_CONTAINER,},
- {FOURCC_disc, "Disc Number", QT_FLAG_CONTAINER,},
- {FOURCC_disk, "Disc Number", QT_FLAG_CONTAINER,},
- {FOURCC_cprt, "Copyright", QT_FLAG_CONTAINER,},
- {FOURCC_cpil, "cpil", QT_FLAG_CONTAINER,},
- {FOURCC_tmpo, "Tempo", QT_FLAG_CONTAINER,},
- {FOURCC_covr, "Cover", QT_FLAG_CONTAINER,},
- {FOURCC_keyw, "Keywords", QT_FLAG_CONTAINER,},
- {FOURCC_kywd, "Keywords", QT_FLAG_CONTAINER,},
- {FOURCC__too, "too", QT_FLAG_CONTAINER,},
- {FOURCC_____, "----", QT_FLAG_CONTAINER,},
- {FOURCC_data, "data", 0, qtdemux_dump_unknown},
- {FOURCC_free, "free", 0,},
- {FOURCC_SVQ3, "SVQ3", 0,},
- {FOURCC_rmra, "rmra", QT_FLAG_CONTAINER,},
- {FOURCC_rmda, "rmda", QT_FLAG_CONTAINER,},
- {FOURCC_rdrf, "rdrf", 0,},
- {FOURCC__gen, "Custom Genre", QT_FLAG_CONTAINER,},
- {FOURCC_ctts, "Composition time to sample", 0, qtdemux_dump_ctts},
- {FOURCC_XiTh, "XiTh", 0},
- {FOURCC_XdxT, "XdxT", 0},
- {FOURCC_loci, "loci", 0},
- {FOURCC_clsf, "clsf", 0},
- {0, "unknown", 0,},
-};
-
-static const int n_qt_node_types =
- sizeof (qt_node_types) / sizeof (qt_node_types[0]);
-
-const QtNodeType *
-qtdemux_type_get (guint32 fourcc)
-{
- int i;
-
- for (i = 0; i < n_qt_node_types; i++) {
- if (G_UNLIKELY (qt_node_types[i].fourcc == fourcc))
- return qt_node_types + i;
- }
-
- GST_WARNING ("unknown QuickTime node type %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
- return qt_node_types + n_qt_node_types - 1;
-}
--- a/gst_plugins_good/gst/qtdemux/qtdemux_types.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_QTDEMUX_TYPES_H__
-#define __GST_QTDEMUX_TYPES_H__
-
-#include <gst/gst.h>
-
-#include "qtdemux.h"
-
-G_BEGIN_DECLS
-
-typedef void (*QtDumpFunc) (GstQTDemux * qtdemux, guint8 * buffer, int depth);
-
-typedef struct _QtNodeType QtNodeType;
-
-#define QT_UINT32(a) (GST_READ_UINT32_BE(a))
-#define QT_UINT24(a) (GST_READ_UINT32_BE(a) >> 8)
-#define QT_UINT16(a) (GST_READ_UINT16_BE(a))
-#define QT_UINT8(a) (GST_READ_UINT8(a))
-#define QT_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0)
-#define QT_FP16(a) ((GST_READ_UINT16_BE(a))/256.0)
-#define QT_FOURCC(a) (GST_READ_UINT32_LE(a))
-#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4))
-
-typedef enum {
- QT_FLAG_NONE = (0),
- QT_FLAG_CONTAINER = (1 << 0)
-} QtFlags;
-
-struct _QtNodeType {
- guint32 fourcc;
- const gchar *name;
- QtFlags flags;
- QtDumpFunc dump;
-};
-
-const QtNodeType *qtdemux_type_get (guint32 fourcc);
-
-G_END_DECLS
-
-#endif /* __GST_QTDEMUX_TYPES_H__ */
--- a/gst_plugins_good/gst/qtdemux/qtpalette.h Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_QTPALLETE_H__
-#define __GST_QTPALLETE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-static const guint32 ff_qt_default_palette_2[2] = {
- 0xffffff, 0x000000
-};
-
-static const guint32 ff_qt_default_palette_4[4] = {
- 0x93655e, 0xffffff, 0xdfd0ab, 0x000000
-};
-
-static const guint32 ff_qt_default_palette_16[16] = {
- 0xfffbff, 0xefd9bb, 0xe8c9b1, 0x93655e,
- 0xfcdee8, 0x9d8891, 0xffffff, 0xffffff,
- 0xffffff, 0x474837, 0x7a5e55, 0xdfd0ab,
- 0xfffbf9, 0xe8cac5, 0x8a7c77, 0x000000
-};
-static const guint32 ff_qt_default_palette_256[256] = {
- 0xFFFFFF, 0xFFFFCC, 0xFFFF99, 0xFFFF66, 0xFFFF33, 0xFFFF00,
- 0xFFCCFF, 0xFFCCCC, 0xFFCC99, 0xFFCC66, 0xFFCC33, 0xFFCC00,
- 0xFF99FF, 0xFF99CC, 0xFF9999, 0xFF9966, 0xFF9933, 0xFF9900,
- 0xFF66FF, 0xFF66CC, 0xFF6699, 0xFF6666, 0xFF6633, 0xFF6600,
- 0xFF33FF, 0xFF33CC, 0xFF3399, 0xFF3366, 0xFF3333, 0xFF3300,
- 0xFF00FF, 0xFF00CC, 0xFF0099, 0xFF0066, 0xFF0033, 0xFF0000,
- 0xCCFFFF, 0xCCFFCC, 0xCCFF99, 0xCCFF66, 0xCCFF33, 0xCCFF00,
- 0xCCCCFF, 0xCCCCCC, 0xCCCC99, 0xCCCC66, 0xCCCC33, 0xCCCC00,
- 0xCC99FF, 0xCC99CC, 0xCC9999, 0xCC9966, 0xCC9933, 0xCC9900,
- 0xCC66FF, 0xCC66CC, 0xCC6699, 0xCC6666, 0xCC6633, 0xCC6600,
- 0xCC33FF, 0xCC33CC, 0xCC3399, 0xCC3366, 0xCC3333, 0xCC3300,
- 0xCC00FF, 0xCC00CC, 0xCC0099, 0xCC0066, 0xCC0033, 0xCC0000,
- 0x99FFFF, 0x99FFCC, 0x99FF99, 0x99FF66, 0x99FF33, 0x99FF00,
- 0x99CCFF, 0x99CCCC, 0x99CC99, 0x99CC66, 0x99CC33, 0x99CC00,
- 0x9999FF, 0x9999CC, 0x999999, 0x999966, 0x999933, 0x999900,
- 0x9966FF, 0x9966CC, 0x996699, 0x996666, 0x996633, 0x996600,
- 0x9933FF, 0x9933CC, 0x993399, 0x993366, 0x993333, 0x993300,
- 0x9900FF, 0x9900CC, 0x990099, 0x990066, 0x990033, 0x990000,
- 0x66FFFF, 0x66FFCC, 0x66FF99, 0x66FF66, 0x66FF33, 0x66FF00,
- 0x66CCFF, 0x66CCCC, 0x66CC99, 0x66CC66, 0x66CC33, 0x66CC00,
- 0x6699FF, 0x6699CC, 0x669999, 0x669966, 0x669933, 0x669900,
- 0x6666FF, 0x6666CC, 0x666699, 0x666666, 0x666633, 0x666600,
- 0x6633FF, 0x6633CC, 0x663399, 0x663366, 0x663333, 0x663300,
- 0x6600FF, 0x6600CC, 0x660099, 0x660066, 0x660033, 0x660000,
- 0x33FFFF, 0x33FFCC, 0x33FF99, 0x33FF66, 0x33FF33, 0x33FF00,
- 0x33CCFF, 0x33CCCC, 0x33CC99, 0x33CC66, 0x33CC33, 0x33CC00,
- 0x3399FF, 0x3399CC, 0x339999, 0x339966, 0x339933, 0x339900,
- 0x3366FF, 0x3366CC, 0x336699, 0x336666, 0x336633, 0x336600,
- 0x3333FF, 0x3333CC, 0x333399, 0x333366, 0x333333, 0x333300,
- 0x3300FF, 0x3300CC, 0x330099, 0x330066, 0x330033, 0x330000,
- 0x00FFFF, 0x00FFCC, 0x00FF99, 0x00FF66, 0x00FF33, 0x00FF00,
- 0x00CCFF, 0x00CCCC, 0x00CC99, 0x00CC66, 0x00CC33, 0x00CC00,
- 0x0099FF, 0x0099CC, 0x009999, 0x009966, 0x009933, 0x009900,
- 0x0066FF, 0x0066CC, 0x006699, 0x006666, 0x006633, 0x006600,
- 0x0033FF, 0x0033CC, 0x003399, 0x003366, 0x003333, 0x003300,
- 0x0000FF, 0x0000CC, 0x000099, 0x000066, 0x000033, 0xEE0000,
- 0xDD0000, 0xBB0000, 0xAA0000, 0x880000, 0x770000, 0x550000,
- 0x440000, 0x220000, 0x110000, 0x00EE00, 0x00DD00, 0x00BB00,
- 0x00AA00, 0x008800, 0x007700, 0x005500, 0x004400, 0x002200,
- 0x001100, 0x0000EE, 0x0000DD, 0x0000BB, 0x0000AA, 0x000088,
- 0x000077, 0x000055, 0x000044, 0x000022, 0x000011, 0xEEEEEE,
- 0xDDDDDD, 0xBBBBBB, 0xAAAAAA, 0x888888, 0x777777, 0x555555,
- 0x444444, 0x222222, 0x111111, 0x000000
-};
-
-static const guint32 ff_qt_grayscale_palette_16[16] = {
- 0xffffff, 0xeeeeee, 0xdddddd, 0xcccccc,
- 0xbbbbbb, 0xaaaaaa, 0x999999, 0x888888,
- 0x777777, 0x666666, 0x555555, 0x444444,
- 0x333333, 0x222222, 0x111111, 0x000000
-};
-
-static const guint32 ff_qt_grayscale_palette_256[256] = {
- 0xffffff, 0xfefefe, 0xfdfdfd, 0xfcfcfc, 0xfbfbfb, 0xfafafa, 0xf9f9f9,
- 0xf8f8f8, 0xf7f7f7, 0xf6f6f6, 0xf5f5f5, 0xf4f4f4, 0xf3f3f3, 0xf2f2f2,
- 0xf1f1f1, 0xf0f0f0, 0xefefef, 0xeeeeee, 0xededed, 0xececec, 0xebebeb,
- 0xeaeaea, 0xe9e9e9, 0xe8e8e8, 0xe7e7e7, 0xe6e6e6, 0xe5e5e5, 0xe4e4e4,
- 0xe3e3e3, 0xe2e2e2, 0xe1e1e1, 0xe0e0e0, 0xdfdfdf, 0xdedede, 0xdddddd,
- 0xdcdcdc, 0xdbdbdb, 0xdadada, 0xd9d9d9, 0xd8d8d8, 0xd7d7d7, 0xd6d6d6,
- 0xd5d5d5, 0xd4d4d4, 0xd3d3d3, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf,
- 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8,
- 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1,
- 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa,
- 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3,
- 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac,
- 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5,
- 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e,
- 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797,
- 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090,
- 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989,
- 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282,
- 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b,
- 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474,
- 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d,
- 0x6c6c6c, 0x6b6b6b, 0x6a6a6a, 0x696969, 0x686868, 0x676767, 0x666666,
- 0x656565, 0x646464, 0x636363, 0x626262, 0x616161, 0x606060, 0x5f5f5f,
- 0x5e5e5e, 0x5d5d5d, 0x5c5c5c, 0x5b5b5b, 0x5a5a5a, 0x595959, 0x585858,
- 0x575757, 0x565656, 0x555555, 0x545454, 0x535353, 0x525252, 0x515151,
- 0x505050, 0x4f4f4f, 0x4e4e4e, 0x4d4d4d, 0x4c4c4c, 0x4b4b4b, 0x4a4a4a,
- 0x494949, 0x484848, 0x474747, 0x464646, 0x454545, 0x444444, 0x434343,
- 0x424242, 0x414141, 0x404040, 0x3f3f3f, 0x3e3e3e, 0x3d3d3d, 0x3c3c3c,
- 0x3b3b3b, 0x3a3a3a, 0x393939, 0x383838, 0x373737, 0x363636, 0x353535,
- 0x343434, 0x333333, 0x323232, 0x313131, 0x303030, 0x2f2f2f, 0x2e2e2e,
- 0x2d2d2d, 0x2c2c2c, 0x2b2b2b, 0x2a2a2a, 0x292929, 0x282828, 0x272727,
- 0x262626, 0x252525, 0x242424, 0x232323, 0x222222, 0x212121, 0x202020,
- 0x1f1f1f, 0x1e1e1e, 0x1d1d1d, 0x1c1c1c, 0x1b1b1b, 0x1a1a1a, 0x191919,
- 0x181818, 0x171717, 0x161616, 0x151515, 0x141414, 0x131313, 0x121212,
- 0x111111, 0x101010, 0x0f0f0f, 0x0e0e0e, 0x0d0d0d, 0x0c0c0c, 0x0b0b0b,
- 0x0a0a0a, 0x090909, 0x080808, 0x070707, 0x060606, 0x050505, 0x040404,
- 0x030303, 0x020202, 0x010101, 0x000000
-};
-
-G_END_DECLS
-
-#endif /* __GST_QTPALETTE_H__ */
--- a/gst_plugins_good/gst/qtdemux/quicktime.c Tue Jul 06 14:35:10 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
- * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "gst/gst-i18n-plugin.h"
-
-#include "qtdemux.h"
-#include "gstrtpxqtdepay.h"
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-#ifdef ENABLE_NLS
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif /* ENABLE_NLS */
-
- /* ensure private tag is registered */
- gst_tag_register (GST_QT_DEMUX_PRIVATE_TAG, GST_TAG_FLAG_META,
- GST_TYPE_BUFFER, "QT atom", "unparsed QT tag atom",
- gst_tag_merge_use_first);
-
- gst_tag_register (GST_QT_DEMUX_CLASSIFICATION_TAG, GST_TAG_FLAG_META,
- G_TYPE_STRING, GST_QT_DEMUX_CLASSIFICATION_TAG, "content classification",
- gst_tag_merge_use_first);
-
- if (!gst_element_register (plugin, "qtdemux",
- GST_RANK_PRIMARY, GST_TYPE_QTDEMUX))
- return FALSE;
-
- if (!gst_element_register (plugin, "rtpxqtdepay",
- GST_RANK_MARGINAL, GST_TYPE_RTP_XQT_DEPAY))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "quicktime",
- "Quicktime support",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
-
-#ifdef SYMBIAN
-EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
-{
- return &gst_plugin_desc;
-}
-
-#endif
--- a/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -284,6 +284,10 @@
int close_devsound(GstDevsoundSink *ds)
{
TRACE_PRN_FN_ENT;
+ CMMFDevSound *dev_sound = 0;
+ dev_sound = (STATIC_CAST(DevSoundWrapper*, ds->handle))->dev_sound;
+ dev_sound->Stop();
+ delete dev_sound;
g_list_foreach(ds->fmt, (GFunc) g_free, NULL);
g_list_free(ds->fmt);
--- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -27,10 +27,11 @@
DevSoundWrapperSrc::DevSoundWrapperSrc()
{
- init_complete = 0;
+ //init_complete = 0;
dev_sound = NULL;
buffersize = 0;
dev_count = 0;
+ speechbitrate = 0;
caps.iRate = EMMFSampleRate8000Hz;
caps.iEncoding = EMMFSoundEncoding16BitPCM;
caps.iChannels = EMMFMono;
@@ -48,15 +49,7 @@
TRACE_PRN_FN_ENT;
TRequestStatus* stat = &(AL->iStatus);
- if (aError == KErrNone)
- {
- init_complete = 1;
- }
- else
- {
- init_complete = 0;
- }
-
+ iCallbackError = aError;
User::RequestComplete(stat, aError);
TRACE_PRN_FN_EXT;
}
@@ -102,6 +95,16 @@
TRACE_PRN_FN_ENT;
TRACE_PRN_N1(_L("DevSoundWrapperSrc::RecordError %d"),aError);
iCallbackError = aError;
+ TRequestStatus* stat = &(AL->iStatus);
+ /// need to check this, error can occure before and after calling
+ /// the StartActiveScheduler and might and might not be waiting for
+ /// completing the request
+ if( AL->IsActive() )
+ {
+ /// need to complete the request for coming out from blocking call.
+ User::RequestComplete(stat, aError);
+ iCallbackError = aError;
+ }
TRACE_PRN_FN_EXT;
}
/**********************************************************/
@@ -176,39 +179,36 @@
int initialize_devsound(GstDevsoundSrc* ds)
{
TRACE_PRN_FN_ENT;
- int ret = 0;
+ //int ret = 0;
DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
handle->AL->InitialiseActiveListener();
- TRAP(ret, handle->dev_sound->InitializeL(*handle, handle->fourcc, EMMFStateRecording));
+ TRAP(handle->iCallbackError, handle->dev_sound->InitializeL(*handle, handle->fourcc, EMMFStateRecording));
- if (ret)
+ if ( handle->iCallbackError )
{
TRACE_PRN_FN_EXT;
- return ret;
+ return handle->iCallbackError;
}
handle->AL->StartActiveScheduler();
- if (handle->init_complete == 1)
+ if (KErrNone == handle->iCallbackError )
{
TMMFPrioritySettings temp;
temp.iPref = (TMdaPriorityPreference) ds->preference;
temp.iPriority = ds->priority;
handle->dev_sound->SetPrioritySettings(temp);
- SetConfigurations(handle);
- ret = KErrNone;
- }
- else
- {
- ret = KErrNotFound;
+ handle->iCallbackError = SetConfigurations(handle);
+
}
- TRACE_PRN_IF_ERR(ret);
+
+ TRACE_PRN_IF_ERR(handle->iCallbackError);
TRACE_PRN_FN_EXT;
- return ret;
+ return handle->iCallbackError;
}
/*********************************************************/
@@ -225,15 +225,7 @@
{
TRACE_PRN_FN_ENT;
DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
- if(handle->dev_sound->IsResumeSupported())
- {
handle->dev_sound->Pause();
- }
- else
- {
- handle->iSamplesRecorded = handle->dev_sound->SamplesRecorded();
- handle->dev_sound->Stop();
- }
TRACE_PRN_FN_EXT;
return 0;
}
@@ -244,12 +236,13 @@
DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
if(handle->dev_sound->IsResumeSupported())
{
- handle->dev_sound->Resume();
+
+ handle->iCallbackError = handle->dev_sound->Resume();
}
else
{
- recordinit(handle);
- initproperties(ds);
+ if( KErrNone == recordinit(handle) )
+ initproperties(ds);
}
TRACE_PRN_FN_EXT;
return 0;
@@ -257,7 +250,7 @@
int open_device(DevSoundWrapperSrc **handle)
{
- int retcode = KErrNone;
+ (*handle)->iCallbackError = KErrNone;
TRACE_PRN_FN_ENT;
(*handle)->dev_count++;
@@ -276,24 +269,26 @@
(*handle)->AL = new CActiveListener;
((*handle)->AL)->asw = new CActiveSchedulerWait();
- TRAP( retcode,(*handle)->dev_sound = CMMFDevSound::NewL() );
+ TRAP( (*handle)->iCallbackError,(*handle)->dev_sound = CMMFDevSound::NewL() );
if (!(*handle)->AL || !((*handle)->AL)->asw || !(*handle)->dev_sound
|| !(*handle)->as)
{
- retcode = KErrNoMemory;
+ return KErrNoMemory;
}
- TRAP(retcode ,(*handle)->iAudoInputRecord = CAudioInput::NewL(*(*handle)->dev_sound));
- RArray<CAudioInput::TAudioInputPreference> inputArray;
+ TRAP((*handle)->iCallbackError ,(*handle)->iAudoInputRecord = CAudioInput::NewL(*(*handle)->dev_sound));
+ if ( KErrNone == (*handle)->iCallbackError )
+ {
+ RArray<CAudioInput::TAudioInputPreference> inputArray;
inputArray.Append( CAudioInput::EDefaultMic );
// Set Audio Input
(*handle)->iAudoInputRecord->SetAudioInputL( inputArray.Array( ) );
inputArray.Close();
-
+ }
TRACE_PRN_FN_EXT;
- return retcode;
+ return (*handle)->iCallbackError;
}
/*********************************************************/
@@ -301,7 +296,9 @@
int close_devsound(GstDevsoundSrc *ds)
{
TRACE_PRN_FN_ENT;
- (STATIC_CAST(DevSoundWrapperSrc*, ds->handle))->dev_sound->Stop();
+ CMMFDevSound *dev_sound= 0;
+ dev_sound = (STATIC_CAST(DevSoundWrapperSrc*, ds->handle))->dev_sound;
+ dev_sound->Stop();
g_list_foreach(ds->supportedbitrates, (GFunc) g_free, NULL);
g_list_free(ds->supportedbitrates);
@@ -309,11 +306,17 @@
g_list_free(ds->fmt);
ds->fmt = NULL;
delete (STATIC_CAST(DevSoundWrapperSrc*, ds->handle))->iAudoInputRecord;
+ delete dev_sound;
delete ds->handle;
TRACE_PRN_FN_EXT;
return 0;
}
/************************************************************/
+void update_devsound_speech_bitrate(DevSoundWrapperSrc *handle, TUint bitrate)
+ {
+ handle->speechbitrate = bitrate;
+ }
+/************************************************************/
int SetConfigurations(DevSoundWrapperSrc *handle)
{
@@ -326,15 +329,7 @@
handle->gain = (handle->dev_sound)->MaxGain();
(handle->dev_sound)->SetGain(handle->gain);
handle->caps.iBufferSize = temp_caps.iBufferSize;
-
- TRAP(ret, (handle->dev_sound)->SetConfigL(handle->caps) );
- if (ret)
- {
- return ret;
- }
-
- (handle->caps) = (handle->dev_sound)->Config();
-
+
switch (handle->fourcc)
{
case KMccFourCCIdG711:
@@ -373,13 +368,33 @@
}
}
+ if (ret)
+ return ret;
+
if (!handle->iSpeechEncoderConfig && handle->fourcc
!= KMMFFourCCCodePCM16)
{
TRAP(ret, handle->iSpeechEncoderConfig
= CSpeechEncoderConfig::NewL(*handle->dev_sound));
+ if (ret)
+ return ret;
+
+ if(handle->speechbitrate > 0)
+ {
+ ret = set_speech_encoder_bit_rate(handle,handle->speechbitrate);
+ if(ret)
+ return ret;
+ }
}
+
+ TRAP(ret, (handle->dev_sound)->SetConfigL(handle->caps) );
+ if (ret)
+ {
+ return ret;
+ }
+
+ (handle->caps) = (handle->dev_sound)->Config();
TRACE_PRN_FN_EXT;
return ret;
@@ -621,27 +636,18 @@
int recordinit(DevSoundWrapperSrc *handle)
{
TRACE_PRN_FN_ENT;
- int ret = 0;
+
((handle)->AL)->InitialiseActiveListener();
handle->iCallbackError = KErrNone;
- TRAP(ret, (handle->dev_sound)->RecordInitL() );
+ TRAP(handle->iCallbackError, (handle->dev_sound)->RecordInitL() );
- if (ret)
+ if (!handle->iCallbackError)
{
- TRACE_PRN_FN_EXT;
- return ret;
- }
- ((handle)->AL)->StartActiveScheduler();
-
- if ((handle->iCallbackError) != KErrNone)
- {
- TRACE_PRN_FN_EXT;
- return (handle->iCallbackError);
+ ((handle)->AL)->StartActiveScheduler();
}
TRACE_PRN_FN_EXT;
- return KErrNone;
-
+ return handle->iCallbackError;
}
/*******************************************************************/
@@ -662,9 +668,8 @@
int pre_init_setconf(GstDevsoundSrc *ds)
{
TRACE_PRN_FN_ENT;
- int ret = 0;
DevSoundWrapperSrc* dsPtr = STATIC_CAST(DevSoundWrapperSrc*, ds->handle);
-
+ dsPtr->iCallbackError = 0;
// NOTE: it is too late for setting prio/pref here
if (ds->pending.preferenceupdate == 1 || ds->pending.priorityupdate == 1)
{
@@ -681,13 +686,13 @@
== 1)
{
- TRAP( ret, (dsPtr->dev_sound)->SetRecordBalanceL(ds->leftbalance,
+ TRAP( dsPtr->iCallbackError, (dsPtr->dev_sound)->SetRecordBalanceL(ds->leftbalance,
ds->rightbalance) );
ds->pending.leftbalanceupdate = FALSE;
ds->pending.rightbalanceupdate = FALSE;
}
TRACE_PRN_FN_EXT;
- return ret;
+ return dsPtr->iCallbackError;
}
/*********************************************************/
void getsupporteddatatypes(GstDevsoundSrc *ds)
@@ -745,3 +750,10 @@
TRACE_PRN_FN_EXT;
}
+int call_back_error(DevSoundWrapperSrc* dsPtr)
+ {
+ TRACE_PRN_FN_ENT;
+ return dsPtr->iCallbackError;
+ TRACE_PRN_FN_EXT;
+ }
+
--- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h Wed Aug 18 10:04:13 2010 +0300
@@ -87,7 +87,7 @@
public:
CActiveListener *AL;
CActiveScheduler *as;
- TInt init_complete;
+ //TInt init_complete;
CMMFBuffer *buffer;
CMMFDevSound *dev_sound;
TMMFCapabilities caps;
@@ -99,6 +99,7 @@
int bufferreadpos;
guint* supportedbitrates;
int iSamplesRecorded;
+ TUint speechbitrate;
CSpeechEncoderConfig* iSpeechEncoderConfig;
CG711EncoderIntfc* iG711EncoderIntfc;
CG729EncoderIntfc* iG729EncoderIntfc;
@@ -177,7 +178,10 @@
int set_ilbc_encoder_mode(DevSoundWrapperSrc *handle,enum TIlbcEncodeMode aEncodeMode);
int set_ilbc_vad_mode(DevSoundWrapperSrc *handle,gboolean aVadMode);
int get_ilbc_vad_mode(DevSoundWrapperSrc *handle,gboolean* aVadMode);
-
+ void update_devsound_speech_bitrate(DevSoundWrapperSrc *handle, TUint bitrate);
+
+ /// getting the call back error
+ int call_back_error(DevSoundWrapperSrc* dsPtr);
#ifdef __cplusplus
}//extern c
--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c Wed Aug 18 10:04:13 2010 +0300
@@ -23,7 +23,8 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
+#include <gst/gst.h>
+#include <e32err.h>
#include <gqueue.h>
#include "common.h"
#include "gstdevsoundsrc.h"
@@ -92,7 +93,7 @@
static gint gst_set_speech_encoder_bit_rate(guint aBitrate);
static gint gst_set_speech_encoder_vad_mode(gboolean aVadMode);
static void gst_Apply_SpeechEncoder_Update(GstDevsoundSrc *devsoundsrc );
-
+static void gst_update_devsound_speech_bitrate(GstDevsoundSrc *devsoundsrc );
/*************************
* G711 Encoder Interface
@@ -181,7 +182,7 @@
CLOSE
};
enum command_to_consumer_thread_enum cmd;
-
+int return_error;
enum
{
LAST_SIGNAL
@@ -213,23 +214,11 @@
"signed = (boolean) TRUE, "
"width = (int) 16, "
"depth = (int) 16, "
- "rate = (int) [ 8000, 48000 ],"
+ "rate = (int) { 8000, 16000, 24000, 32000, 48000 },"
"channels = (int) [ 1, 2 ]; "
"audio/amr, "
- "rate = (int) [ 8000, 48000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/x-alaw, "
- "rate = (int) [ 8000, 48000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/g729, "
- "rate = (int) [ 8000, 48000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/ilbc, "
- "rate = (int) [ 8000, 48000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/x-mulaw, "
- "rate = (int) [ 8000, 48000 ], "
- "channels = (int) [ 1, 2 ]")
+ "rate = (int) 8000, "
+ "channels = (int) [ 1, 2 ]; ")
);
static GstElementClass *parent_class= NULL;
@@ -407,7 +396,17 @@
TUint8* gBuffer;
GstBuffer* pushBuffer= NULL;
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "StartDevSoundThread ",NULL);
- open_devsound(&(devsoundsrc->handle));
+ int ret = open_devsound(&(devsoundsrc->handle));
+
+ if( 0 != ret )
+ {
+ pthread_mutex_lock(&(create_mutex1));
+ return_error = ret;
+ pthread_cond_signal(&(create_condition1));
+ pthread_mutex_unlock(&(create_mutex1));
+ //return_error = ret;
+ pthread_exit(NULL);
+ }
getsupporteddatatypes(devsoundsrc);
@@ -419,6 +418,7 @@
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After Record Init ",NULL);
pthread_mutex_lock(&(create_mutex1));
+ return_error = ret;
pthread_cond_signal(&(create_condition1));
pthread_mutex_unlock(&(create_mutex1));
@@ -435,10 +435,28 @@
// without putting it to play state
if ( cmd != CLOSE )
{
- initialize_devsound(devsoundsrc);
-
- recordinit(devsoundsrc->handle);
- initproperties(devsoundsrc);
+ gst_update_devsound_speech_bitrate(devsoundsrc);
+ ret = initialize_devsound(devsoundsrc);
+ if( 0 == ret )
+ {
+ ret = recordinit(devsoundsrc->handle);
+ if( 0 == ret )
+ initproperties(devsoundsrc);
+
+ }
+ /// if initialization of devsound failed, return error,
+ /// on return other thread will send CLOSE cmd to exit from thread.
+ if( ret )
+ {
+ pthread_mutex_lock(&(create_mutex1));
+ return_error = ret;
+ pthread_cond_signal(&(create_condition1));
+ pthread_mutex_unlock(&(create_mutex1));
+
+ pthread_mutex_lock(&create_mutex1);
+ pthread_cond_wait(&create_condition1, &create_mutex1);
+ pthread_mutex_unlock(&create_mutex1);
+ }
}
while (TRUE)
@@ -460,7 +478,7 @@
case RECORDING:
{
pre_init_setconf(devsoundsrc);
- gst_Apply_SpeechEncoder_Update(devsoundsrc);
+// gst_Apply_SpeechEncoder_Update(devsoundsrc);
gst_Apply_G711Encoder_Update(devsoundsrc);
gst_Apply_G729Encoder_Update(devsoundsrc );
gst_Apply_IlbcEncoder_Update(devsoundsrc );
@@ -510,6 +528,7 @@
break;
}
pthread_mutex_lock(&(create_mutex1));
+ return_error = call_back_error(devsoundsrc->handle);
pthread_cond_signal(&(create_condition1));
pthread_mutex_unlock(&(create_mutex1));
@@ -687,6 +706,7 @@
static gboolean gst_devsound_src_start(GstBaseSrc * bsrc)
{
GstBuffer *tmp_gstbuffer=NULL;
+ gboolean ret = TRUE;
GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_start ENTER ",NULL);
pthread_mutex_init(&create_mutex1, NULL);
@@ -710,6 +730,7 @@
consumer_thread_state = CONSUMER_THREAD_INITIALIZING;
cmd = OPEN;
+ return_error = 0;
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Before Thread Create ",NULL);
pthread_create(&ds_thread, NULL, StartDevSoundThread, (void *)src);
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "After Thread Create ",NULL);
@@ -718,11 +739,12 @@
{
pthread_mutex_lock(&create_mutex1);
pthread_cond_wait(&create_condition1, &create_mutex1);
+ ret = !return_error; // should be TRUE on no Error, and FALSE at ERROR.
pthread_mutex_unlock(&create_mutex1);
}
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "AFter Mutex Wait in START ",NULL);
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_start EXIT ",NULL);
- return TRUE;
+ return ret;
/* ERRORS */
}
@@ -800,6 +822,7 @@
{
GstDevsoundSrc *dsrc= GST_DEVSOUND_SRC(src);
int bufferpos=0;
+ int ret = 0;
if(!g_queue_get_length(dataqueue) && (dsrc->eosreceived == TRUE))
{
@@ -865,26 +888,41 @@
else
{
cmd = RECORDING;
+ return_error = 0;
pthread_mutex_lock(&(create_mutex1));
pthread_cond_signal(&(create_condition1));
pthread_mutex_unlock(&(create_mutex1));
pthread_mutex_lock(&(create_mutex1));
pthread_cond_wait(&(create_condition1), &(create_mutex1));
+ ret = return_error;
pthread_mutex_unlock(&(create_mutex1));
}
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "AFTER WAIT in CREATE ",NULL);
}
-
+ if( KErrInUse == ret || KErrDied == ret || KErrAccessDenied == ret )
+ {
+ // post error as pre-emption
+ GST_ELEMENT_ERROR (src, RESOURCE, BUSY,
+ (("Pre-emption error.")),
+ ("streaming paused because higher priority app requested resource, Err(%d)", ret));
+
+ return GST_FLOW_UNEXPECTED;
+ }
+ else if( KErrNone != ret )
+ {
+ // no need to post error as base src will post error.
+ return GST_FLOW_ERROR;
+ }
//gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "Before POP in CREATE ",NULL);
GST_OBJECT_LOCK(dsrc);
popBuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
GST_OBJECT_UNLOCK(dsrc);
- //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "AFTER POP in CREATE ",NULL);
- if(!popBuffer)
- {
- return GST_FLOW_UNEXPECTED;
- }
+
+ if(!popBuffer )
+ {
+ return GST_FLOW_UNEXPECTED;
+ }
if(dsrc->firstTimeInit != kPlayed)
{
dsrc->prevbuffersize = gst_base_src_get_blocksize(src);
@@ -952,12 +990,15 @@
if(cmd == PAUSE)
{
cmd = RESUME;
+ return_error = 0;
pthread_mutex_lock(&create_mutex1);
pthread_cond_signal(&create_condition1);
pthread_mutex_unlock(&create_mutex1);
pthread_mutex_lock(&create_mutex1);
pthread_cond_wait(&create_condition1, &create_mutex1);
+ if( return_error )
+ ret = GST_STATE_CHANGE_FAILURE;
pthread_mutex_unlock(&create_mutex1);
}
break;
@@ -973,12 +1014,15 @@
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
cmd = PAUSE;
+ return_error = 0;
pthread_mutex_lock(&create_mutex1);
pthread_cond_signal(&create_condition1);
pthread_mutex_unlock(&create_mutex1);
pthread_mutex_lock(&create_mutex1);
pthread_cond_wait(&create_condition1, &create_mutex1);
+ if( return_error )
+ ret = GST_STATE_CHANGE_FAILURE;
pthread_mutex_unlock(&create_mutex1);
break;
default:
@@ -1052,7 +1096,14 @@
return 0;
}
-
+static void gst_update_devsound_speech_bitrate(GstDevsoundSrc *devsoundsrc )
+ {
+ if(customInfaceUpdate.speechbitrateupdate == TRUE)
+ {
+ update_devsound_speech_bitrate(devsoundsrc->handle,speechbitrate);
+ customInfaceUpdate.speechbitrateupdate = FALSE;
+ }
+ }
static void gst_Apply_SpeechEncoder_Update(GstDevsoundSrc *devsoundsrc )
{
if(customInfaceUpdate.speechbitrateupdate == TRUE)
@@ -1251,6 +1302,7 @@
//reset_devsound(sink->handle);
src->eosreceived = TRUE;
cmd = STOP;
+ return_error = 0;
pthread_mutex_lock(&create_mutex1);
pthread_cond_signal(&create_condition1);
pthread_mutex_unlock(&create_mutex1);
--- a/gst_plugins_symbian/tsrc/gstreamertestmodule/group/bld.inf Tue Jul 06 14:35:10 2010 +0300
+++ b/gst_plugins_symbian/tsrc/gstreamertestmodule/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -27,25 +27,9 @@
PRJ_TESTEXPORTS
#ifdef FF_GSTREAMER
-/epoc32/release/winscw/udeb/libgstcoreelements.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstcoreelements.dll
-/epoc32/release/winscw/udeb/libgstcoreindexers.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstcoreindexers.dll
-/epoc32/release/winscw/udeb/libgstwavparse.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstwavparse.dll
-/epoc32/release/winscw/udeb/libgstwavenc.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstwavenc.dll
-/epoc32/release/winscw/udeb/libgstdevsoundsink.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstdevsoundsink.dll
-/epoc32/release/winscw/udeb/libgstdevsoundsrc.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstdevsoundsrc.dll
-/epoc32/release/winscw/udeb/libgstaudioconvert.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstaudioconvert.dll
-/epoc32/release/winscw/udeb/libgstaudioresample.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstaudioresample.dll
-/epoc32/release/winscw/udeb/libgstaudiotestsrc.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstaudiotestsrc.dll
-/epoc32/release/winscw/udeb/libgstdecodebin.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstdecodebin.dll
-/epoc32/release/winscw/udeb/libgstdecodebin2.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstdecodebin2.dll
-/epoc32/release/winscw/udeb/libgstplaybin.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstplaybin.dll
-/epoc32/release/winscw/udeb/libgsttypefindfunctions.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgsttypefindfunctions.dll
-/epoc32/release/winscw/udeb/libgstqueue2.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstlibgstqueue2.dll
-/epoc32/release/winscw/udeb/libgstaudiorate.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstaudiorate.dll
-/epoc32/release/winscw/udeb/libgstautodetect.dll /epoc32/release/winscw/udeb/z/sys/bin/plugins/libgstautodetect.dll
-
../conf/GStreamerTestClass.cfg /epoc32/winscw/c/TestFramework/GStreamerTestClass.cfg
../init/GStreamerTestClass.ini /epoc32/winscw/c/TestFramework/GStreamerTestClass.ini
+../init/TestFramework.ini /epoc32/winscw/c/TestFramework/TestFramework.ini
#endif
PRJ_TESTMMPFILES
--- a/gstreamer_core/tsrc/check/elements/gstqueue/src/gstqueue.c Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/check/elements/gstqueue/src/gstqueue.c Wed Aug 18 10:04:13 2010 +0300
@@ -324,13 +324,13 @@
/* pushing gives away my reference ... */
gst_pad_push (mysrcpad, gst_buffer_ref (buffer3));
- //g_mutex_lock (check_mutex);
+ g_mutex_lock (check_mutex);
/* start the src-task briefly leak buffer3 */
gst_pad_set_active (mysinkpad, TRUE);
- //g_cond_wait (check_cond, check_mutex);
- //g_mutex_unlock (check_mutex);
+ g_cond_wait (check_cond, check_mutex);
+ g_mutex_unlock (check_mutex);
/// wait for second thread to read buffer.
- sleep(2);
+ //sleep(2);
gst_pad_set_active (mysinkpad, FALSE);
GST_DEBUG ("stopping");
@@ -416,12 +416,12 @@
/* pushing gives away my reference ... */
gst_pad_push (mysrcpad, buffer3);
- //g_mutex_lock (check_mutex);
+ g_mutex_lock (check_mutex);
/* start the src-task briefly and leak buffer1 */
gst_pad_set_active (mysinkpad, TRUE);
- //g_cond_wait (check_cond, check_mutex);
- //g_mutex_unlock (check_mutex);
- sleep(2);
+ g_cond_wait (check_cond, check_mutex);
+ g_mutex_unlock (check_mutex);
+ //sleep(2);
gst_pad_set_active (mysinkpad, FALSE);
GST_DEBUG ("stopping");
--- a/gstreamer_core/tsrc/check/pipelines/parse-launch/src/parse-launch.c Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/check/pipelines/parse-launch/src/parse-launch.c Wed Aug 18 10:04:13 2010 +0300
@@ -457,6 +457,7 @@
void delayed_link()
{
+ GstElement* pa;
xmlfile = "delayed_link";
std_log(LOG_FILENAME_LINE, "Test Started delayed_link");
fail_unless (gst_element_register (NULL, "parsetestelement",
@@ -466,6 +467,10 @@
* a test element based on bin, which contains a fakesrc and a sometimes
* pad-template, and trying to link to a fakesink. When the bin transitions
* to paused it adds a pad, which should get linked to the fakesink */
+
+ pa = gst_element_factory_make ("parsetestelement", NULL);
+ gst_object_unref (pa);
+ //g_free (pa);
run_delayed_test
("parsetestelement name=src ! fakesink silent=true name=sink", "sink",
TRUE);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/aac_record/group/aacrecord.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET aac_record.exe
+TARGETTYPE EXE
+UID 0 0x055301c3
+
+EPOCHEAPSIZE 0x10000 0x100000
+#ifdef EKA2
+LANG SC
+CAPABILITY All -Tcb
+VENDORID VID_DEFAULT
+
+#endif
+
+
+
+MACRO HAVE_CONFIG_H
+
+
+USERINCLUDE ..
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../../../../..
+USERINCLUDE ../../../../libs/gst/check
+USERINCLUDE ../../../../gst
+USERINCLUDE ../../../..
+USERINCLUDE ../../../../libs
+
+MW_LAYER_SYSTEMINCLUDE
+OS_LAYER_LIBC_SYSTEMINCLUDE
+
+OS_LAYER_GLIB_SYSTEMINCLUDE
+MW_LAYER_GSTREAMER_SYSTEMINCLUDE
+
+
+
+SOURCEPATH ../src
+
+SOURCE aacrecord.c
+
+
+LIBRARY euser.lib libc.lib
+LIBRARY libpthread.lib
+LIBRARY libdl.lib
+LIBRARY libglib.lib
+LIBRARY libgmodule.lib
+
+LIBRARY libgobject.lib
+LIBRARY libgthread.lib
+LIBRARY libm.lib
+LIBRARY libz.lib
+LIBRARY libgstreamer.lib
+LIBRARY libgstbase.lib
+LIBRARY libgstcontroller.lib
+
+STATICLIBRARY libcrt0.lib
+//VENDORID VID_DEFAULT
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/aac_record/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTMMPFILES
+aacrecord.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/aac_record/src/aacrecord.c Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,313 @@
+
+#include <gst/gst_global.h>
+#include <stdlib.h>
+#include <gst/gst.h>
+#include <gst/gstelement.h>
+#include <string.h>
+#define LOG_FILE "c:\\logs\\launch_logs.txt"
+#include "std_log_result.h"
+#define LOG_FILENAME_LINE __FILE__, __LINE__
+
+static guint _bitrate = 128000;
+static guint _channels = 1;
+static guint _sample_rate = 8000;
+static guint _aac_profile = 2; // default is LC
+static guint _enable_logs = 1;
+static guint _record_duration = 10000; // recording duration
+#define REC_FILENAME_LEN 256
+static char rec_filename[REC_FILENAME_LEN];
+
+GstElement *pipeline;
+
+#define ENABLE_LOGS
+
+#ifdef ENABLE_LOGS
+#define RET_GST_ERR_STR(var, level, str) \
+ if ( level == var )\
+return str;
+
+static inline const char* _gst_err_cat( GstDebugLevel level)
+{
+
+ RET_GST_ERR_STR(level,GST_LEVEL_NONE,"");
+ RET_GST_ERR_STR(level,GST_LEVEL_ERROR,"E ");
+ RET_GST_ERR_STR(level,GST_LEVEL_WARNING,"W ");
+ RET_GST_ERR_STR(level,GST_LEVEL_INFO,"I ");
+ RET_GST_ERR_STR(level,GST_LEVEL_DEBUG,"D ");
+ RET_GST_ERR_STR(level,GST_LEVEL_LOG, "L ");
+ RET_GST_ERR_STR(level,GST_LEVEL_FIXME, "F ");
+ RET_GST_ERR_STR(level,GST_LEVEL_MEMDUMP, "M ");
+ return "";
+}
+static inline const char* _str_aac_profile()
+{
+ if ( _aac_profile == 0) return "auto";
+ if ( _aac_profile == 2) return "lc";
+ if ( _aac_profile == 5) return "he";
+ return "unknown";
+}
+
+static FILE* log_fp = 0;
+
+static void open_log_fp()
+{
+ if (!log_fp)
+ {
+ snprintf(rec_filename, REC_FILENAME_LEN, "C://Data//gst_br%d_c%d_sr%d_%s.log", _bitrate, _channels, _sample_rate, _str_aac_profile());
+
+ log_fp = fopen(rec_filename, "w");
+ if (!log_fp)
+ return;
+ }
+}
+
+
+static void _gstLogFunction (GstDebugCategory *category,
+ GstDebugLevel level,
+ const gchar *file,
+ const gchar *function,
+ gint line,
+ GObject *object,
+ GstDebugMessage *message,
+ gpointer data)
+{
+
+ // if ( (level != GST_LEVEL_ERROR) /*&& (level != GST_LEVEL_DEBUG)*/ && (level != GST_LEVEL_WARNING) )
+ // return;
+
+ open_log_fp();
+
+ fprintf(log_fp, "%s : %s \n", _gst_err_cat(level), gst_debug_message_get(message));
+ fflush(log_fp);
+
+}
+#endif // ENABLE_LOGS
+
+// Local Functions
+static gboolean
+bus_call (GstBus *bus,
+ GstMessage *msg,
+ gpointer data)
+{
+
+ GMainLoop *loop = (GMainLoop *) data;
+
+ open_log_fp();
+
+ fprintf(log_fp,"[msg] %s from %s\n", GST_MESSAGE_TYPE_NAME(msg), GST_MESSAGE_SRC_NAME (msg));
+
+ switch (GST_MESSAGE_TYPE (msg)) {
+ case GST_MESSAGE_EOS:
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (pipeline));
+ g_main_loop_quit(loop);
+ break;
+ case GST_MESSAGE_ERROR: {
+ gchar *debug;
+ GError *err;
+ gst_message_parse_error (msg, &err, &debug);
+ fprintf(log_fp, "[ERROR] %s\n", debug);
+ g_free (debug);
+ g_error_free (err);
+ g_main_loop_quit(loop);
+ break;
+ }
+#if 0
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState state;
+ // gst_element_get_state (GstElement * element,
+ // GstState * state,
+ // GstState * pending,
+ // GstClockTime timeout);
+
+ gst_element_get_state(GST_ELEMENT(pipeline),&state,NULL,-1);
+ if(state == GST_STATE_PLAYING)
+ {
+
+ }
+
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+ static gboolean
+quit_loop (gpointer data)
+{
+ GST_DEBUG("quiting loop");
+ gst_element_send_event (pipeline, gst_event_new_eos ());
+ return TRUE;
+}
+
+
+static void parse_args(int argc, char** argv)
+{
+
+ gint cur = 1;
+ while ( argv[cur] && cur < argc )
+ {
+ if( !strcmp(argv[cur],"-br") ) _bitrate = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-c") ) _channels = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-sr") ) _sample_rate = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-p") ) _aac_profile = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-l") ) _enable_logs = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-d") ) _record_duration = atoi(argv[cur+1]);
+
+ cur+=2;
+ }
+}
+
+// Currently unused, TODO merge all recording usecases in this app.
+#if 0
+char gst_pipeline[4096];
+
+static inline GstElement* __parse_wav_pipeline()
+{
+ snprintf(gst_pipeline, 4096, "devsoundsrc ! audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)%d, channels=(int)%d, endianness=(int)1234 ! wavenc ! filesink location=C://Data//wav_c%d_sr%d.wav",
+ _sample_rate, _channels , _channels, _sample_rate );
+ pipeline = gst_parse_launch( gst_pipeline,0);
+ return pipeline;
+}
+static inline GstElement* __get_wav_pipeline()
+{
+ GstCaps* caps;
+ GstElement *devsoundsrc,*filesink,*wavenc;
+ GError *error = NULL;
+
+ pipeline = gst_pipeline_new ("pipeline");
+ devsoundsrc = gst_element_factory_make ("devsoundsrc", "devsoundsrc");
+ wavenc = gst_element_factory_make ("wavenc", "wavenc");
+ filesink = gst_element_factory_make ("filesink", "filesink");
+
+ snprintf(rec_filename, REC_FILENAME_LEN, "C:\\\\data\\\\wav_c%d_sr%d.wav", _channels, _sample_rate);
+ g_object_set (G_OBJECT (filesink), "location", rec_filename, NULL);
+
+
+ GST_DEBUG("filtered linking...");
+
+ caps = gst_caps_new_simple ("audio/x-raw-int",
+ "width", G_TYPE_INT, 16,
+ "depth", G_TYPE_INT, 16,
+ "signed",G_TYPE_BOOLEAN, TRUE,
+ "endianness",G_TYPE_INT, G_BYTE_ORDER,
+ "rate", G_TYPE_INT, _sample_rate,
+ "channels", G_TYPE_INT, _channels, NULL);
+
+ gst_bin_add_many (GST_BIN (pipeline), devsoundsrc, wavenc, filesink, NULL);
+ gst_element_link_filtered (devsoundsrc, wavenc, caps);
+
+
+ gst_element_link (wavenc, filesink);
+ gst_caps_unref (caps);
+
+ return pipeline;
+
+}
+#endif
+
+static inline GstElement* __get_aac_pipeline()
+{
+ GstCaps* caps;
+ GstElement *devsoundsrc,*filesink,*nokiaaacenc,*mp4mux;
+ GstPad *qtsinkpad,*aacencsrcpad;
+
+ pipeline = gst_pipeline_new ("pipeline");
+ devsoundsrc = gst_element_factory_make ("devsoundsrc", "devsoundsrc");
+ nokiaaacenc = gst_element_factory_make ("nokiaaacenc", "nokiaaacenc");
+ mp4mux = gst_element_factory_make ("mp4mux", "mp4mux");
+ filesink = gst_element_factory_make ("filesink", "filesink");
+
+ snprintf(rec_filename, REC_FILENAME_LEN, "C:\\\\data\\\\rec-aac_br%d_c%d_sr%d_%s.mp4", _bitrate, _channels, _sample_rate,
+ _str_aac_profile());
+ g_object_set (G_OBJECT (filesink), "location", rec_filename, NULL);
+
+ //GST_DEBUG("set bitrate on aacenc");
+ g_object_set (G_OBJECT (nokiaaacenc), "bitrate", _bitrate, NULL);
+
+ //if ( _aac_profile )
+ g_object_set (G_OBJECT (nokiaaacenc), "profile", _aac_profile, NULL);
+
+
+ GST_DEBUG("filtered linking...");
+
+ caps = gst_caps_new_simple ("audio/x-raw-int",
+ "width", G_TYPE_INT, 16,
+ "depth", G_TYPE_INT, 16,
+ "signed",G_TYPE_BOOLEAN, TRUE,
+ "endianness",G_TYPE_INT, G_BYTE_ORDER,
+ "rate", G_TYPE_INT, _sample_rate,
+ "channels", G_TYPE_INT, _channels, NULL);
+
+ gst_bin_add_many (GST_BIN (pipeline), devsoundsrc, nokiaaacenc, mp4mux, filesink, NULL);
+ gst_element_link_filtered (devsoundsrc, nokiaaacenc, caps);
+
+ qtsinkpad = gst_element_get_request_pad( mp4mux, "audio_%d");
+ aacencsrcpad = gst_element_get_pad( nokiaaacenc, "src");
+ if (gst_pad_link (aacencsrcpad,qtsinkpad) != GST_PAD_LINK_OK) {
+
+ GST_ERROR("gst_pad_link (aacencsrcpad,qtsinkpad) failed");
+ return NULL;
+ }
+ gst_element_link (mp4mux, filesink);
+ gst_caps_unref (caps);
+
+ return pipeline;
+}
+
+int main (int argc, char *argv[])
+{
+ GMainLoop *loop;
+
+
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ setenv("GST_DEBUG","2",1);
+#endif // ENABLE_LOGS
+
+ gst_init (NULL, NULL);
+
+ parse_args(argc, argv);
+
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ gst_debug_add_log_function( _gstLogFunction, 0);
+#endif // ENABLE_LOGS
+
+ GST_DEBUG("args : br %d chans %d sr %d ", _bitrate, _channels, _sample_rate);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+
+ //pipeline = __get_wav_pipeline();
+ //pipeline = __parse_wav_pipeline();
+ pipeline = __get_aac_pipeline();
+
+
+ /* start playing */
+ gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)), bus_call, loop);
+ // watchdog timer
+ //g_timeout_add (_record_duration * 1.5, quit_program, 0);
+
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+ g_timeout_add (_record_duration, quit_loop, loop);
+
+
+ g_main_loop_run (loop);
+
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (pipeline));
+
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ fclose(log_fp);
+#endif // ENABLE_LOGS
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/amr_record/group/amr_record.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET amr_record.exe
+TARGETTYPE EXE
+UID 0 0x0AB22A00
+
+EPOCHEAPSIZE 0x10000 0x100000
+#ifdef EKA2
+LANG SC
+CAPABILITY All -Tcb
+VENDORID VID_DEFAULT
+
+#endif
+
+
+
+MACRO HAVE_CONFIG_H
+
+USERINCLUDE /sf/mw/gstreamer/gst_plugins_symbian/gst/devsound
+USERINCLUDE ..
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../../../../..
+USERINCLUDE ../../../../libs/gst/check
+USERINCLUDE ../../../../gst
+USERINCLUDE ../../../..
+USERINCLUDE ../../../../libs
+
+MW_LAYER_SYSTEMINCLUDE
+OS_LAYER_LIBC_SYSTEMINCLUDE
+
+OS_LAYER_GLIB_SYSTEMINCLUDE
+MW_LAYER_GSTREAMER_SYSTEMINCLUDE
+
+
+
+SOURCEPATH ../src
+
+SOURCE amr_record.c
+
+
+LIBRARY euser.lib libc.lib
+LIBRARY libpthread.lib
+LIBRARY libdl.lib
+LIBRARY libglib.lib
+LIBRARY libgmodule.lib
+
+LIBRARY libgobject.lib
+LIBRARY libgthread.lib
+LIBRARY libm.lib
+LIBRARY libz.lib
+LIBRARY libgstreamer.lib
+LIBRARY libgstbase.lib
+LIBRARY libgstcontroller.lib
+LIBRARY libgstdevsoundext.lib
+LIBRARY SpeechEncoderConfig.lib
+
+STATICLIBRARY libcrt0.lib
+//VENDORID VID_DEFAULT
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/amr_record/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+
+
+PRJ_TESTMMPFILES
+amr_record.mmp
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/amr_record/src/amr_record.c Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,240 @@
+
+#include <gst/gst_global.h>
+#include <stdlib.h>
+#include <gst/gst.h>
+#include <gst/gstelement.h>
+#include <string.h>
+#define LOG_FILE "c:\\logs\\amr_record_logs.txt"
+#include "std_log_result.h"
+#include <gstspeechencoderconfig.h>
+#define LOG_FILENAME_LINE __FILE__, __LINE__
+#define LOG_FILENAME_LEN 256
+#define _DEBUG 1
+
+static char log_filename[LOG_FILENAME_LEN];
+
+static guint bitrate = 0;
+static guint record_duration = 10000;
+static guint _enable_logs = 0;
+
+static GstSpeechEncoderConfigIntfc* iface;
+
+
+#define ENABLE_LOGS
+
+#ifdef ENABLE_LOGS
+#define RET_GST_ERR_STR(var, level, str) \
+ if ( level == var )\
+return str;
+
+static inline const char* _gst_err_cat( GstDebugLevel level)
+{
+
+ RET_GST_ERR_STR(level,GST_LEVEL_NONE,"");
+ RET_GST_ERR_STR(level,GST_LEVEL_ERROR,"E ");
+ RET_GST_ERR_STR(level,GST_LEVEL_WARNING,"W ");
+ RET_GST_ERR_STR(level,GST_LEVEL_INFO,"I ");
+ RET_GST_ERR_STR(level,GST_LEVEL_DEBUG,"D ");
+ RET_GST_ERR_STR(level,GST_LEVEL_LOG, "L ");
+ RET_GST_ERR_STR(level,GST_LEVEL_FIXME, "F ");
+ RET_GST_ERR_STR(level,GST_LEVEL_MEMDUMP, "M ");
+ return "";
+}
+
+static FILE* log_fp = 0;
+
+static void open_log_fp()
+{
+ if (!log_fp)
+ {
+ snprintf(log_filename, LOG_FILENAME_LEN, "C:\\logs\\testframework\\gst_amr_br%d.log", bitrate);
+
+ log_fp = fopen(log_filename, "w");
+ if (!log_fp)
+ return;
+ }
+}
+
+
+static void _gstLogFunction (GstDebugCategory *category,
+ GstDebugLevel level,
+ const gchar *file,
+ const gchar *function,
+ gint line,
+ GObject *object,
+ GstDebugMessage *message,
+ gpointer data)
+{
+ open_log_fp();
+
+ fprintf(log_fp, "%s : %s \n", _gst_err_cat(level), gst_debug_message_get(message));
+ fflush(log_fp);
+
+}
+#endif // ENABLE_LOGS
+
+static void parse_args(int argc, char** argv)
+{
+
+ gint cur = 1;
+ while ( argv[cur] && cur < argc )
+ {
+ GST_WARNING("br:%d, record_duration:%d \n",bitrate,record_duration);
+ if( !strcmp(argv[cur],"-br") ) bitrate = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-l") ) _enable_logs = atoi(argv[cur+1]);
+ else if( !strcmp(argv[cur],"-d") ) record_duration = atoi(argv[cur+1]);
+
+ cur+=2;
+ }
+}
+
+
+GstElement *pipeline, *source, *amrmux,*sink;
+GstBus *bus;
+GMainLoop *loop;
+
+static gboolean
+bus_call (GstBus *bus,
+ GstMessage *msg,
+ gpointer data)
+ {
+#ifdef ENABLE_LOGS
+ if(_enable_logs)
+ {
+ open_log_fp();
+ fprintf(log_fp,"[msg] %s from %s\n", GST_MESSAGE_TYPE_NAME(msg), GST_MESSAGE_SRC_NAME (msg));
+ }
+#endif
+
+ switch (GST_MESSAGE_TYPE (msg)) {
+ case GST_MESSAGE_EOS:
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ g_main_loop_quit(loop);
+ gst_object_unref (GST_OBJECT (pipeline));
+ break;
+
+ case GST_MESSAGE_ERROR: {
+ gchar *debug;
+ GError *err;
+ gst_message_parse_error (msg, &err, &debug);
+ g_free (debug);
+ g_print ("Error: %s\n", err->message);
+ g_error_free (err);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TRUE;
+ }
+
+static gboolean
+quit_loop (gpointer data)
+{
+ GST_WARNING("Sending EOS\n");
+ gst_element_send_event (pipeline, gst_event_new_eos ());
+ return TRUE;
+}
+
+int main (int argc, char *argv[])
+{
+ char filename[1024];
+ GstCaps* caps;
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ setenv("GST_DEBUG","2",1);
+#endif // ENABLE_LOGS
+
+ parse_args(argc,argv);
+
+ gst_init (&argc, &argv);
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ gst_debug_add_log_function( _gstLogFunction, 0);
+#endif // ENABLE_LOGS
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* create elements */
+ pipeline = gst_pipeline_new ("audio-player");
+ source = gst_element_factory_make ("devsoundsrc", "audio-source");
+ amrmux = gst_element_factory_make ("amrmux", "amrmux");
+ sink = gst_element_factory_make ("filesink", "sink");
+
+ if (!pipeline || !source || !amrmux || !sink) {
+ g_print ("One element could not be created\n");
+ GST_ERROR("One element could not be created\n");
+ return -1;
+ }
+ if(bitrate > 0)
+ {
+ snprintf(filename, 1024, "C:\\data\\amr_record_%d.amr", bitrate );
+ }
+ else
+ {
+ snprintf(filename, 1024, "C:\\data\\amr_record.amr" );
+ }
+
+ /* set filename property on the file source. Also add a message handler. */
+ g_object_set (G_OBJECT (sink), "location", filename, NULL);
+ /* put all elements in a bin */
+ gst_bin_add_many (GST_BIN (pipeline),source, amrmux,sink, NULL);
+
+ caps = gst_caps_new_simple ("audio/amr",
+ "width", G_TYPE_INT, 8,
+ "depth", G_TYPE_INT, 8,
+ "signed",G_TYPE_BOOLEAN, TRUE,
+ "endianness",G_TYPE_INT, G_BYTE_ORDER,
+ "rate", G_TYPE_INT, 8000,
+ "channels", G_TYPE_INT, 1, NULL);
+
+ if(!gst_element_link_filtered (source, amrmux, caps))
+ {
+ GST_ERROR("Linking source, amrmux failed\n");
+ return -1;
+ }
+
+ if(!gst_element_link (amrmux, sink))
+ {
+ GST_ERROR("Linking amrmux,sink failed\n");
+ return -1;
+ }
+
+ gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)), bus_call, loop);
+ iface = GST_SPEECH_ENCODER_CONFIG_GET_IFACE(source);
+ if(!iface)
+ {
+ GST_ERROR("Speech Encoder Interface NULL \n");
+ return -1;
+ }
+ if (bitrate > 0)
+ {
+ GST_WARNING("Setting bitrate %d \n",bitrate);
+ iface->SetBitrate(bitrate);
+ }
+
+ /* Now set to playing and iterate. */
+ g_print ("Setting to PLAYING\n");
+ GST_WARNING("Setting to Playing \n");
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ iface->GetBitrate(&bitrate);
+
+ g_timeout_add (record_duration, quit_loop, loop);
+
+ g_main_loop_run (loop);
+ /* clean up nicely */
+ GST_WARNING("Returned, stopping playback\n");
+
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (pipeline));
+
+#ifdef ENABLE_LOGS
+ if ( _enable_logs )
+ fclose(log_fp);
+#endif // ENABLE_LOGS
+
+ g_print ("completed playing audio\n");
+ return 0;
+}
+
--- a/gstreamer_core/tsrc/examples/group/bld.inf Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/examples/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -19,7 +19,10 @@
* Description:
*
*/
+#include "../amr_record/group/bld.inf"
+#include "../wav_record/group/bld.inf"
+#include "../aac_record/group/bld.inf"
#include "../gstseek/group/bld.inf"
#include "../helloworld/group/bld.inf"
#include "../controller/group/bld.inf"
--- a/gstreamer_core/tsrc/examples/gstseek/src/gstseek.c Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/examples/gstseek/src/gstseek.c Wed Aug 18 10:04:13 2010 +0300
@@ -62,6 +62,26 @@
return TRUE;
}
+static gboolean cb_autoplug( GstBin * *bin,
+ GstPad *pad,
+ GstCaps *caps,
+ gpointer user_data)
+{
+ GstCaps* sinkcaps = NULL;
+ gboolean supported = FALSE;
+
+ GstPad* sinkpad = gst_element_get_pad( sink, "sink");
+ sinkcaps = gst_pad_get_caps( sinkpad );
+ supported = gst_caps_is_subset( caps, sinkcaps );
+
+ if( supported )
+ {
+ //link_with_devsoundsink = TRUE;
+ return FALSE;
+ }
+ return TRUE;
+}
+
static void
cb_newpad (GstElement *decodebin,
GstPad *pad,
@@ -191,7 +211,7 @@
gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)), bus_call, loop);
g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
- //g_signal_connect (decoder, "autoplug-continue", G_CALLBACK (cb_autoplug), NULL);
+ g_signal_connect (decoder, "autoplug-continue", G_CALLBACK (cb_autoplug), NULL);
g_timeout_add (1000/*in mili sec*/, (GSourceFunc) cb_get_position, NULL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/wav_record/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_TESTEXPORTS
+
+
+PRJ_TESTMMPFILES
+wav_record.mmp
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/wav_record/group/wav_record.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET wav_record.exe
+TARGETTYPE EXE
+UID 0 0x055311c3
+
+EPOCHEAPSIZE 0x10000 0x100000
+#ifdef EKA2
+LANG SC
+CAPABILITY All -Tcb
+VENDORID VID_DEFAULT
+
+#endif
+
+
+
+MACRO HAVE_CONFIG_H
+
+
+USERINCLUDE ..
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../libs/gst/base
+USERINCLUDE ../gst
+USERINCLUDE ../../../../..
+USERINCLUDE ../../../../libs/gst/check
+USERINCLUDE ../../../../gst
+USERINCLUDE ../../../..
+USERINCLUDE ../../../../libs
+
+MW_LAYER_SYSTEMINCLUDE
+OS_LAYER_LIBC_SYSTEMINCLUDE
+
+OS_LAYER_GLIB_SYSTEMINCLUDE
+MW_LAYER_GSTREAMER_SYSTEMINCLUDE
+
+
+
+SOURCEPATH ../src
+
+SOURCE wav_record.c
+
+
+LIBRARY euser.lib libc.lib
+LIBRARY libpthread.lib
+LIBRARY libdl.lib
+LIBRARY libglib.lib
+LIBRARY libgmodule.lib
+
+LIBRARY libgobject.lib
+LIBRARY libgthread.lib
+LIBRARY libm.lib
+LIBRARY libz.lib
+LIBRARY libgstreamer.lib
+LIBRARY libgstbase.lib
+LIBRARY libgstcontroller.lib
+
+STATICLIBRARY libcrt0.lib
+//VENDORID VID_DEFAULT
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/examples/wav_record/src/wav_record.c Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,148 @@
+
+#include <gst/gst_global.h>
+#include <stdlib.h>
+#include <gst/gst.h>
+#include <gst/gstelement.h>
+#include <string.h>
+#define LOG_FILE "c:\\logs\\wav_record_logs.txt"
+#include "std_log_result.h"
+#define LOG_FILENAME_LINE __FILE__, __LINE__
+
+void create_xml(int result)
+{
+
+ if(result)
+ {
+ assert_failed = 1;
+ }
+
+ testResultXml(xmlfile);
+ close_log_file();
+
+ if(result)
+ {
+ exit (-1);
+ }
+
+}
+
+GstElement *pipeline, *source, *wavenc,*sink;
+GstBus *bus;
+GMainLoop *loop;
+
+static gboolean
+bus_call (GstBus *bus,
+ GstMessage *msg,
+ gpointer data)
+{
+ switch (GST_MESSAGE_TYPE (msg)) {
+ case GST_MESSAGE_EOS:
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ g_main_loop_quit(loop);
+ gst_object_unref (GST_OBJECT (pipeline));
+ //std_log(LOG_FILENAME_LINE, "Test Successful");
+ create_xml(0);
+ break;
+ case GST_MESSAGE_ERROR: {
+ gchar *debug;
+ GError *err;
+ gst_message_parse_error (msg, &err, &debug);
+ g_free (debug);
+ g_print ("Error: %s\n", err->message);
+ g_error_free (err);
+ //std_log(LOG_FILENAME_LINE, "Test Failed");
+ create_xml(1);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+quit_loop (gpointer data)
+{
+ gst_element_send_event (pipeline, gst_event_new_eos ());
+
+}
+
+
+/// exe name record_duration sampling_rate chans width
+int main (int argc, char *argv[])
+{
+ char filename[1024];
+ GstCaps* caps;
+ int sampling_rate = 8000;
+ int chans = 1;
+ int width = 16;
+ guint record_duration = 10000;
+
+ if (argc > 1) {
+ record_duration = (guint) atoi( argv[1] ) * 1000;
+ }
+
+ if (argc > 2) {
+ sampling_rate = (int) atoi( argv[2] );
+ }
+
+ if (argc > 3) {
+ chans = (int) atoi( argv[3] );
+ }
+
+ if (argc > 4) {
+ width = (int) atoi( argv[4] );
+ }
+
+
+ gst_init (&argc, &argv);
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* create elements */
+ pipeline = gst_pipeline_new ("audio-player");
+ source = gst_element_factory_make ("devsoundsrc", "audio-source");
+ wavenc = gst_element_factory_make ("wavenc", "mp3parse");
+ sink = gst_element_factory_make ("filesink", "sink");
+
+ if (!pipeline || !source || !wavenc || !sink) {
+ g_print ("One element could not be created\n");
+ return -1;
+ }
+ snprintf(filename, 1024, "C:\\data\\wav_record_samp-%d-chans-%d-duration-%dsec.wav",
+ sampling_rate, chans,record_duration/1000 );
+
+ /* set filename property on the file source. Also add a message handler. */
+ g_object_set (G_OBJECT (sink), "location", filename, NULL);
+ /* put all elements in a bin */
+ gst_bin_add_many (GST_BIN (pipeline),source, wavenc,sink, NULL);
+
+ caps = gst_caps_new_simple ("audio/x-raw-int",
+ "width", G_TYPE_INT, width,
+ "depth", G_TYPE_INT, width,
+ "signed",G_TYPE_BOOLEAN, TRUE,
+ "endianness",G_TYPE_INT, G_BYTE_ORDER,
+ "rate", G_TYPE_INT, sampling_rate,
+ "channels", G_TYPE_INT, chans, NULL);
+
+ gst_element_link_filtered (source, wavenc, caps);
+ gst_element_link (wavenc, sink);
+
+ gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)), bus_call, loop);
+ //g_signal_connect (decoder, "pad-added", G_CALLBACK (new_pad_cb),pipeline);
+ /* Now set to playing and iterate. */
+ g_print ("Setting to PLAYING\n");
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ g_timeout_add (record_duration, quit_loop, loop);
+ g_print ("Running\n");
+ g_main_loop_run (loop);
+ /* clean up nicely */
+ g_print ("Returned, stopping playback\n");
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ g_print ("Deleting pipeline\n");
+ gst_object_unref (GST_OBJECT (pipeline));
+
+ g_print ("completed palying audio\n");
+ return 0;
+}
+
--- a/gstreamer_core/tsrc/group/bld.inf Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -26,6 +26,6 @@
//#include "../gstreamertestcases_suite1/group/bld.inf"
//#include "../gstreamertestcases_suite2/group/bld.inf"
//#include "../gstreamertestcases_suite3/group/bld.inf"
-
+//#include "../gstreamertestcases_suite4/group/bld.inf"
// End of File
--- a/gstreamer_core/tsrc/gstreamertestcases/conf/GstreamerTestCases.cfg Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/gstreamertestcases/conf/GstreamerTestCases.cfg Wed Aug 18 10:04:13 2010 +0300
@@ -6,9 +6,9 @@
[Endtest]
[Test]
-title gstaudioconvert.exe test_int_conversion
+title gstaudioconvert.exe test_int_conversion
create GstreamerTestCases foobar
-foobar Example gstaudioconvert.exe test_int_conversion
+foobar Example gstaudioconvert.exe test_int_conversion
delete foobar
[Endtest]
@@ -735,12 +735,14 @@
delete foobar
[Endtest]
+/*
[Test]
title gdpdepay.exe test_streamheader
create GstreamerTestCases foobar
foobar Example gdpdepay.exe test_streamheader
delete foobar
[Endtest]
+*/
[Test]
title gstaudioresample.exe test_perfect_stream
@@ -791,12 +793,14 @@
delete foobar
[Endtest]
+/*
[Test]
title stress_playbin.exe
create GstreamerTestCases foobar
foobar Example stress_playbin.exe c:\data\gstreamer\gsttestfiles\khuda.wav
delete foobar
[Endtest]
+*/
[Test]
title gstsimple-launch-lines.exe test_element_negotiation
--- a/gstreamer_core/tsrc/gstreamertestcases/group/bld.inf Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/gstreamertestcases/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -32,7 +32,7 @@
// 'abld test export'
../conf/GstreamerTestCases.cfg /epoc32/winscw/c/TestFramework/GstreamerTestCases.cfg
-../init/GstreamerTestCases.ini /epoc32/winscw/c/TestFramework/GstreamerTestCases.ini
+../init/gstreamertestcases.ini /epoc32/winscw/c/TestFramework/gstreamertestcases.ini
../init/testframework.ini /epoc32/winscw/c/TestFramework/testframework.ini
PRJ_EXPORTS
--- a/gstreamer_core/tsrc/gstreamertestcases_suite1/conf/gstreamertestcases_suite1.cfg Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite1/conf/gstreamertestcases_suite1.cfg Wed Aug 18 10:04:13 2010 +0300
@@ -217,12 +217,14 @@
delete foobar
[Endtest]
+/*
[Test]
title manual_gstquery.exe
create gstreamertestcases_suite1 foobar
foobar Example manual_gstquery.exe C:\\data\\gstreamer\\khuda.wav
delete foobar
[Endtest]
+*/
[Test]
title manual_dynamic.exe
@@ -252,13 +254,14 @@
delete foobar
[Endtest]
+/*
[Test]
title parse-disabled.exe test_parse_launch_errors
create gstreamertestcases_suite1 foobar
foobar Example parse-disabled.exe test_parse_launch_errors
delete foobar
[Endtest]
-
+*/
[Test]
title simple-launch-lines.exe test_2_elements
create gstreamertestcases_suite1 foobar
@@ -288,9 +291,9 @@
[Endtest]
[Test]
-title gstmessage.exe test_parsing
+title gstmessage.exe test_parsing
create gstreamertestcases_suite1 foobar
-foobar Example gstmessage.exe test_parsing
+foobar Example gstmessage.exe test_parsing
delete foobar
[Endtest]
@@ -924,14 +927,14 @@
delete foobar
[Endtest]
-
+/*
[Test]
title gstobject.exe test_fail_abstract_new
create gstreamertestcases_suite1 foobar
foobar Example gstobject.exe test_fail_abstract_new
delete foobar
[Endtest]
-
+*/
[Test]
title gstcaps.exe test_from_string
--- a/gstreamer_core/tsrc/gstreamertestcases_suite3/conf/gstreamertestcases_suite3.cfg Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite3/conf/gstreamertestcases_suite3.cfg Wed Aug 18 10:04:13 2010 +0300
@@ -158,12 +158,14 @@
delete foobar
[Endtest]
+/*
[Test]
title parse-launch.exe expected_to_fail_pipes
create gstreamertestcases_suite3 foobar
foobar Example parse-launch.exe expected_to_fail_pipes
delete foobar
-[Endtest]
+[Endtest]
+*/
[Test]
title parse-launch.exe leaking_fail_pipes
@@ -181,7 +183,7 @@
/* playback testing */
-
+/*
[Test]
title launch.exe AAC_8k_64kbps_mono_Queen.aac
create gstreamertestcases_suite3 foobar
@@ -377,7 +379,6 @@
[Endtest]
-/*
[Test]
title launch.exe f:\data\MP3_11.025k_40kbps_mono_Test2.mp3
create gstreamertestcases_suite3 foobar
@@ -640,7 +641,9 @@
foobar SetTimeout 20
delete foobar
[Endtest]
-
+*/
+/*
+file is not proper so commented.
[Test]
title launch.exe AAC Reliabity testcase
create gstreamertestcases_suite3 foobar
@@ -648,7 +651,8 @@
foobar SetTimeout 20
delete foobar
[Endtest]
-
+*/
+/*
[Test]
title launch.exe EAAC Reliabity testcase
create gstreamertestcases_suite3 foobar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/Bwins/gstreamertestcases_suite4u.def Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ ?LibEntryL@@YAPAVCScriptBase@@AAVCTestModuleIf@@@Z @ 1 NONAME ; class CScriptBase * LibEntryL(class CTestModuleIf &)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/EABI/gstreamertestcases_suite4u.def Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ _Z9LibEntryLR13CTestModuleIf @ 1 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/conf/gstreamertestcases_suite4.cfg Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,280 @@
+/*
+[Test]
+title aac rec 16Kbps 8KHz
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 16000 -sr 8000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 32Kbps 8KHz LC 20Secs
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 32000 -sr 8000 -p 2 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 128Kbps 8KHz Auto 10Secs
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 128000 -sr 8000 -p 0 -l 0 -d 10000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 128Kbps 11025Hz LC
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 128000 -sr 11025 -p 2 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 64Kbps 16KHz LC 40Secs
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 64000 -sr 16000 -p 2 -l 0 -d 40000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 96Kbps 16KHz Auto 20Secs
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 96000 -sr 16000 -p 0 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 256Kbps 16KHz HE
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 256000 -sr 16000 -p 5 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 128Kbps 22050Hz LC
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 128000 -sr 22050 -p 2 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 128Kbps 32KHz LC
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 128000 -sr 32000 -p 2 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 160Kbps 32KHz Auto
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 160000 -sr 32000 -p 0 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 224Kbps 32KHz HE 30Secs
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 224000 -sr 32000 -p 5 -l 0 -d 30000
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 256Kbps 44100Hz 2 chan Auto
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 256000 -sr 44100 -c 2 -p 0 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 224Kbps 48KHz 2chan LC
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 224000 -sr 48000 -c 2 -p 2 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 128Kbps 48KHz 2chan HE
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 128000 -sr 48000 -c 2 -p 5 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 192Kbps 48KHz HE
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 192000 -sr 48000 -p 5 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title aac rec 160Kbps 32KHz HE
+create gstreamertestcases_suite4 foobar
+foobar Example aac_record.exe -br 160000 -sr 32000 -p 5 -l 0
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record default
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 4.75Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 4750 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 5.15Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 5150 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 5.9Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 5900 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 6.7Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 6700 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 7.4Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 7400 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 7.95Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 7950 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 10.2Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 10200 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 12.2Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 12200 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 5Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 5000 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title amr_record 8Kbps 20sec
+create gstreamertestcases_suite4 foobar
+foobar Example amr_record.exe -br 8000 -l 0 -d 20000
+delete foobar
+[Endtest]
+
+[Test]
+title wav_record.exe default
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe
+delete foobar
+[Endtest]
+
+[Test]
+title wav_record.exe 10 8000 1 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 8000 1 16
+delete foobar
+[Endtest]
+
+[Test]
+title wav_record.exe 10 8000 2 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 8000 2 16
+delete foobar
+[Endtest]
+*/
+
+/*[Test]
+title wav_record.exe 10 16000 1 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 16000 1 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 16000 2 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 16000 2 16
+delete foobar
+[Endtest]
+*/
+/*
+[Test]
+title wav_record.exe 10 24000 1 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 24000 1 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 24000 2 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 24000 2 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 32000 1 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 32000 1 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 32000 2 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 32000 2 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 48000 1 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 48000 1 16
+delete foobar
+[Endtest]
+
+
+[Test]
+title wav_record.exe 10 48000 2 16
+create gstreamertestcases_suite4 foobar
+foobar Example wav_record.exe 10 48000 2 16
+delete foobar
+[Endtest]
+
+
+*/
+
+
+
Binary file gstreamer_core/tsrc/gstreamertestcases_suite4/data/khuda.wav has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/group/GstreamerTestCases_DoxyFile.txt Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,246 @@
+#
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Description:
+#
+#
+#
+
+# Doxyfile 1.4.1
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = GstreamerTestCases
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = \GstreamerTestCases\
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = YES
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = \GstreamerTestCases\
+FILE_PATTERNS = *.h \
+ *.rh \
+ *.hrh
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = YES
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = YES
+TOC_EXPAND = YES
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = YES
+RTF_OUTPUT = Doc
+COMPACT_RTF = YES
+RTF_HYPERLINKS = YES
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = NONSHARABLE_CLASS
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/group/GstreamerTestCases_suite4.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,81 @@
+/*TYPE TESTCLASS*/
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+TARGET gstreamertestcases_suite4.dll
+TARGETTYPE dll
+UID 0x1000008D 0x101FB7E7
+
+CAPABILITY ALL -TCB
+
+/* Remove comments and replace 0x00000000 with correct vendor id */
+// VENDORID 0x00000000
+/* Remove comments and replace 0x00000000 with correct secure id */
+// SECUREID 0x00000000
+
+//TARGETPATH ?target_path
+//DEFFILE GstreamerTestCases.def
+
+USERINCLUDE ../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+SOURCEPATH ../src
+
+SOURCE GstreamerTestCases.cpp
+SOURCE GstreamerTestCasesBlocks.cpp
+
+//RESOURCE resource_file
+//RESOURCE resource_file2
+
+LIBRARY euser.lib
+LIBRARY stiftestinterface.lib
+LIBRARY stiftestengine.lib
+
+LANG SC
+
+/*
+START WINS
+?wins_specific_information
+END
+
+START MARM
+?marm_specific_information
+END
+*/
+// Other possible keywords:
+
+// DOCUMENT ?file, that is not compiled, but added to MSVC project workspace (i.e. release notes)
+/*
+START BITMAP ?target
+TARGETPATH ?emulated_path_on_target_machine
+HEADER
+SOURCE ?color_depth ?source_bitmap
+END
+*/
+// DEFFILE ?filename
+// AIF ?filename
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/group/bld.inf Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description:
+*
+*/
+
+
+PRJ_PLATFORMS
+// specify the platforms your component needs to be built for here
+// defaults to WINS MARM so you can ignore this if you just build these
+
+ DEFAULT
+
+PRJ_TESTEXPORTS
+// NOTE: If using ARS requirements all export operations should be done under this.
+// 'abld test export'
+../conf/gstreamertestcases_suite4.cfg /epoc32/winscw/c/TestFramework/gstreamertestcases_suite4.cfg
+../init/gstreamertestcases_suite4.ini /epoc32/winscw/c/TestFramework/gstreamertestcases_suite4.ini
+../init/testframework.ini /epoc32/winscw/c/TestFramework/testframework.ini
+
+
+
+
+PRJ_EXPORTS
+// Specify the source file followed by its destination here
+// copy will be used to copy the source file to its destination
+// If there's no destination then the source file will be copied
+// to the same name in /epoc32/include
+// Example:
+
+
+PRJ_TESTMMPFILES
+
+ GstreamerTestCases_suite4.mmp
+
+PRJ_MMPFILES
+//GstreamerTestCases_suite4.mmp
+
+ // GstreamerTestCases_nrm.mmp
+
+// Specify the .mmp files required for building the important component
+// releasables.
+//
+// Specify "tidy" if the component you need to build doesn't need to be
+// released. Specify "ignore" if the MMP file exists but should be
+// ignored.
+// Example:
+
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/group/gstreamer_testcases.pkg Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,169 @@
+; ============================================================================
+; Name : gstreamer_testcases.pkg
+; Part of : Gstreamer project
+; Description : Package file for all gstreamer test binaries
+;
+; Version : %version: bh1mmcf#3 %
+;
+; Copyright © 2002-2006 Nokia. All rights reserved.
+; This material, including documentation and any related computer
+; programs, is protected by copyright controlled by Nokia. All
+; rights are reserved. Copying, including reproducing, storing,
+; adapting or translating, any or all of this material requires the
+; prior written consent of Nokia. This material also contains
+; confidential information which may not be disclosed to others
+; without the prior written consent of Nokia.
+; ============================================================================
+
+;Languages
+&EN
+
+;Header
+#{"gstreamer_testcases.pkg"},(0x2001F45C),1,0,0, TYPE=SU
+
+;Supports S60 3.0
+[0x101F7961], 0, 0, 0, {"S60ProductID"}
+
+;Localised Vendor name
+%{"Nokia Testing EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+
+;gstreamer dll
+
+"\epoc32\winscw\c\gstreamer\plugins_list\gst_dll_2001F41F.txt" - "c:\gstreamer\plugins_list\gst_dll_2001F41F.txt"
+"\epoc32\release\armv5\urel\gstreamertestcases_suite4.dll"-"!:\sys\bin\gstreamertestcases_suite4.dll"
+
+;gstregistry exe
+
+"\epoc32\release\armv5\urel\GSTRegistryGenerator.exe" -"!:\sys\bin\GSTRegistryGenerator.exe",FR,RI
+
+;gstreamer-core test exe's
+
+"\epoc32\release\armv5\urel\cleanup.exe"-"!:\sys\bin\cleanup.exe"
+"\epoc32\release\armv5\urel\createelementcore.exe"-"!:\sys\bin\createelementcore.exe"
+"\epoc32\release\armv5\urel\element_gstfakesink.exe"-"!:\sys\bin\element_gstfakesink.exe"
+"\epoc32\release\armv5\urel\element_gstfakesrc.exe"-"!:\sys\bin\element_gstfakesrc.exe"
+"\epoc32\release\armv5\urel\element_gstfdsrc.exe"-"!:\sys\bin\element_gstfdsrc.exe"
+"\epoc32\release\armv5\urel\element_gstfilesink.exe"-"!:\sys\bin\element_gstfilesink.exe"
+"\epoc32\release\armv5\urel\element_gstfilesrc.exe"-"!:\sys\bin\element_gstfilesrc.exe"
+"\epoc32\release\armv5\urel\element_gstidentity.exe"-"!:\sys\bin\element_gstidentity.exe"
+"\epoc32\release\armv5\urel\element_gstmultiqueue.exe"-"!:\sys\bin\element_gstmultiqueue.exe"
+"\epoc32\release\armv5\urel\element_gstqueue.exe"-"!:\sys\bin\element_gstqueue.exe"
+"\epoc32\release\armv5\urel\element_gsttee.exe"-"!:\sys\bin\element_gsttee.exe"
+"\epoc32\release\armv5\urel\gst.exe"-"!:\sys\bin\gst.exe"
+"\epoc32\release\armv5\urel\gstadapter.exe"-"!:\sys\bin\gstadapter.exe"
+"\epoc32\release\armv5\urel\gstbasesrc.exe"-"!:\sys\bin\gstbasesrc.exe"
+"\epoc32\release\armv5\urel\gstbin.exe"-"!:\sys\bin\gstbin.exe"
+"\epoc32\release\armv5\urel\gstbuffer.exe"-"!:\sys\bin\gstbuffer.exe"
+"\epoc32\release\armv5\urel\gstbus.exe"-"!:\sys\bin\gstbus.exe"
+"\epoc32\release\armv5\urel\gstcaps.exe"-"!:\sys\bin\gstcaps.exe"
+"\epoc32\release\armv5\urel\gstcollectpads.exe"-"!:\sys\bin\gstcollectpads.exe"
+"\epoc32\release\armv5\urel\gstcontroller.exe"-"!:\sys\bin\gstcontroller.exe"
+"\epoc32\release\armv5\urel\gstelement.exe"-"!:\sys\bin\gstelement.exe"
+"\epoc32\release\armv5\urel\gstevent.exe"-"!:\sys\bin\gstevent.exe"
+"\epoc32\release\armv5\urel\gstgdp.exe"-"!:\sys\bin\gstgdp.exe"
+"\epoc32\release\armv5\urel\gstghostpad.exe"-"!:\sys\bin\gstghostpad.exe"
+"\epoc32\release\armv5\urel\gstgstnetclientclock.exe"-"!:\sys\bin\gstgstnetclientclock.exe"
+"\epoc32\release\armv5\urel\gstgstnettimeprovider.exe"-"!:\sys\bin\gstgstnettimeprovider.exe"
+"\epoc32\release\armv5\urel\gstindex.exe"-"!:\sys\bin\gstindex.exe"
+"\epoc32\release\armv5\urel\gstinterface.exe"-"!:\sys\bin\gstinterface.exe"
+"\epoc32\release\armv5\urel\gstiterator.exe"-"!:\sys\bin\gstiterator.exe"
+"\epoc32\release\armv5\urel\gstlibsabi.exe"-"!:\sys\bin\gstlibsabi.exe"
+"\epoc32\release\armv5\urel\gstmessage.exe"-"!:\sys\bin\gstmessage.exe"
+"\epoc32\release\armv5\urel\gstminiobject.exe"-"!:\sys\bin\gstminiobject.exe"
+"\epoc32\release\armv5\urel\gstobject.exe"-"!:\sys\bin\gstobject.exe"
+"\epoc32\release\armv5\urel\gstpad.exe"-"!:\sys\bin\gstpad.exe"
+"\epoc32\release\armv5\urel\gstparamspecs.exe"-"!:\sys\bin\gstparamspecs.exe"
+"\epoc32\release\armv5\urel\gstpipeline.exe"-"!:\sys\bin\gstpipeline.exe"
+"\epoc32\release\armv5\urel\gstplugin.exe"-"!:\sys\bin\gstplugin.exe"
+"\epoc32\release\armv5\urel\gstpoll.exe"-"!:\sys\bin\gstpoll.exe"
+"\epoc32\release\armv5\urel\gstquery.exe"-"!:\sys\bin\gstquery.exe"
+"\epoc32\release\armv5\urel\gstregistry.exe"-"!:\sys\bin\gstregistry.exe"
+"\epoc32\release\armv5\urel\gstsegment.exe"-"!:\sys\bin\gstsegment.exe"
+"\epoc32\release\armv5\urel\gstsinks.exe"-"!:\sys\bin\gstsinks.exe"
+"\epoc32\release\armv5\urel\gststates.exe"-"!:\sys\bin\gststates.exe"
+"\epoc32\release\armv5\urel\gststructure.exe"-"!:\sys\bin\gststructure.exe"
+"\epoc32\release\armv5\urel\gstsystemclock.exe"-"!:\sys\bin\gstsystemclock.exe"
+"\epoc32\release\armv5\urel\gsttag.exe"-"!:\sys\bin\gsttag.exe"
+"\epoc32\release\armv5\urel\gsttagsetter.exe"-"!:\sys\bin\gsttagsetter.exe"
+"\epoc32\release\armv5\urel\gsttask.exe"-"!:\sys\bin\gsttask.exe"
+"\epoc32\release\armv5\urel\gsttypefindhelper.exe"-"!:\sys\bin\gsttypefindhelper.exe"
+"\epoc32\release\armv5\urel\gsturi.exe"-"!:\sys\bin\gsturi.exe"
+"\epoc32\release\armv5\urel\gstutils.exe"-"!:\sys\bin\gstutils.exe"
+"\epoc32\release\armv5\urel\gstvalue.exe"-"!:\sys\bin\gstvalue.exe"
+"\epoc32\release\armv5\urel\helloworld.exe"-"!:\sys\bin\helloworld.exe"
+"\epoc32\release\armv5\urel\launch.exe"-"!:\sys\bin\launch.exe"
+"\epoc32\release\armv5\urel\manual_dynamic.exe"-"!:\sys\bin\manual_dynamic.exe"
+"\epoc32\release\armv5\urel\manual_ghostpad.exe"-"!:\sys\bin\manual_ghostpad.exe"
+"\epoc32\release\armv5\urel\manual_gstbin.exe"-"!:\sys\bin\manual_gstbin.exe"
+"\epoc32\release\armv5\urel\manual_gstdecodebin.exe"-"!:\sys\bin\manual_gstdecodebin.exe"
+"\epoc32\release\armv5\urel\manual_gstelementcreate.exe"-"!:\sys\bin\manual_gstelementcreate.exe"
+"\epoc32\release\armv5\urel\manual_gstelementfactory.exe"-"!:\sys\bin\manual_gstelementfactory.exe"
+"\epoc32\release\armv5\urel\manual_gstelementget.exe"-"!:\sys\bin\manual_gstelementget.exe"
+"\epoc32\release\armv5\urel\manual_gstelementlink.exe"-"!:\sys\bin\manual_gstelementlink.exe"
+"\epoc32\release\armv5\urel\manual_gstelementmake.exe"-"!:\sys\bin\manual_gstelementmake.exe"
+"\epoc32\release\armv5\urel\manual_gstinit.exe"-"!:\sys\bin\manual_gstinit.exe"
+"\epoc32\release\armv5\urel\manual_gstpad.exe"-"!:\sys\bin\manual_gstpad.exe"
+"\epoc32\release\armv5\urel\manual_gstplaybin.exe"-"!:\sys\bin\manual_gstplaybin.exe"
+"\epoc32\release\armv5\urel\manual_gstquery.exe"-"!:\sys\bin\manual_gstquery.exe"
+"\epoc32\release\armv5\urel\manual_helloworld.exe"-"!:\sys\bin\manual_helloworld.exe"
+"\epoc32\release\armv5\urel\manual_typefind.exe"-"!:\sys\bin\manual_typefind.exe"
+"\epoc32\release\armv5\urel\metadata.exe"-"!:\sys\bin\metadata.exe"
+"\epoc32\release\armv5\urel\mp3launch.exe"-"!:\sys\bin\mp3launch.exe"
+"\epoc32\release\armv5\urel\parse-disabled.exe"-"!:\sys\bin\parse-disabled.exe"
+"\epoc32\release\armv5\urel\parse-launch.exe"-"!:\sys\bin\parse-launch.exe"
+"\epoc32\release\armv5\urel\simple-launch-lines.exe"-"!:\sys\bin\simple-launch-lines.exe"
+"\epoc32\release\armv5\urel\stress.exe"-"!:\sys\bin\stress.exe"
+"\epoc32\release\armv5\urel\testaudioexample.exe"-"!:\sys\bin\testaudioexample.exe"
+"\epoc32\release\armv5\urel\testgstadapter.exe"-"!:\sys\bin\testgstadapter.exe"
+"\epoc32\release\armv5\urel\testqueue.exe"-"!:\sys\bin\testqueue.exe"
+"\epoc32\release\armv5\urel\typefind.exe"-"!:\sys\bin\typefind.exe"
+"\epoc32\release\armv5\urel\gstseek.exe"-"!:\sys\bin\gstseek.exe"
+"\epoc32\release\armv5\urel\wav_record.exe"-"!:\sys\bin\wav_record.exe"
+"\epoc32\release\armv5\urel\amr_record.exe"-"!:\sys\bin\amr_record.exe"
+"\epoc32\release\armv5\urel\aac_record.exe"-"!:\sys\bin\aac_record.exe"
+
+;gst_plugins_base test exe's
+
+"\epoc32\release\armv5\urel\gstadder.exe"-"!:\sys\bin\gstadder.exe"
+"\epoc32\release\armv5\urel\gstaudioconvert.exe"-"!:\sys\bin\gstaudioconvert.exe"
+"\epoc32\release\armv5\urel\gstaudiorate.exe"-"!:\sys\bin\gstaudiorate.exe"
+"\epoc32\release\armv5\urel\gstaudioresample.exe"-"!:\sys\bin\gstaudioresample.exe"
+"\epoc32\release\armv5\urel\gstaudiotestsrc.exe"-"!:\sys\bin\gstaudiotestsrc.exe"
+"\epoc32\release\armv5\urel\createelementbase.exe"-"!:\sys\bin\createelementbase.exe"
+"\epoc32\release\armv5\urel\gstdecodebin.exe"-"!:\sys\bin\gstdecodebin.exe"
+"\epoc32\release\armv5\urel\gdpdepay.exe"-"!:\sys\bin\gdpdepay.exe"
+"\epoc32\release\armv5\urel\multifdsink.exe"-"!:\sys\bin\multifdsink.exe"
+"\epoc32\release\armv5\urel\playbin.exe"-"!:\sys\bin\playbin.exe"
+"\epoc32\release\armv5\urel\gstsubparse.exe"-"!:\sys\bin\gstsubparse.exe"
+"\epoc32\release\armv5\urel\volume.exe"-"!:\sys\bin\volume.exe"
+"\epoc32\release\armv5\urel\clock-selection.exe"-"!:\sys\bin\clock-selection.exe"
+"\epoc32\release\armv5\urel\states.exe"-"!:\sys\bin\states.exe"
+"\epoc32\release\armv5\urel\fft.exe"-"!:\sys\bin\fft.exe"
+;"\epoc32\release\armv5\urel\gstnetbuffer.exe"-"!:\sys\bin\gstnetbuffer.exe"
+"\epoc32\release\armv5\urel\pbutils.exe"-"!:\sys\bin\pbutils.exe"
+"\epoc32\release\armv5\urel\gst_plugin_rtp.exe"-"!:\sys\bin\gst_plugin_rtp.exe"
+"\epoc32\release\armv5\urel\gst_plugin_tag.exe"-"!:\sys\bin\gst_plugin_tag.exe"
+"\epoc32\release\armv5\urel\taudio.exe"-"!:\sys\bin\taudio.exe"
+"\epoc32\release\armv5\urel\gstsimple-launch-lines.exe"-"!:\sys\bin\gstsimple-launch-lines.exe"
+"\epoc32\release\armv5\urel\gststreamheader.exe"-"!:\sys\bin\gststreamheader.exe"
+"\epoc32\release\armv5\urel\stress_playbin.exe"-"!:\sys\bin\stress_playbin.exe"
+
+;"\epoc32\release\armv5\urel\ffmpegcolorspace.exe"-"!:\sys\bin\ffmpegcolorspace.exe"
+;"\epoc32\release\armv5\urel\addstream.exe"-"!:\sys\bin\addstream.exe"
+;"\epoc32\release\armv5\urel\video.exe"-"!:\sys\bin\video.exe"
+;"\epoc32\release\armv5\urel\typefindfunctions.exe" -"!:\sys\bin\typefindfunctions.exe"
+;"\epoc32\release\armv5\urel\videorate.exe"-"!:\sys\bin\videorate.exe"
+
+
+
+;dependecy files
+
+;Testframework.ini and conf files
+
+"..\conf\gstreamertestcases_suite4.cfg"-"c:\TestFramework\gstreamertestcases_suite4.cfg"
+"..\init\gstreamertestcases_suite4.ini"-"c:\TestFramework\gstreamertestcases_suite4.ini"
+"..\init\TestFramework.ini"-"c:\TestFramework\TestFramework.ini"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/inc/GstreamerTestCases.h Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description: STIF testclass declaration
+*
+*/
+
+
+#ifndef GSTREAMERTESTCASES_H
+#define GSTREAMERTESTCASES_H
+
+// INCLUDES
+#include <StifLogger.h>
+#include <TestScripterInternal.h>
+#include <StifTestModule.h>
+#include <TestclassAssert.h>
+
+// CONSTANTS
+//const ?type ?constant_var = ?constant;
+
+// MACROS
+//#define ?macro ?macro_def
+#define TEST_CLASS_VERSION_MAJOR 0
+#define TEST_CLASS_VERSION_MINOR 0
+#define TEST_CLASS_VERSION_BUILD 0
+
+// Logging path
+_LIT( KGstreamerTestCasesLogPath, "\\logs\\testframework\\GstreamerTestCases\\" );
+// Log file
+_LIT( KGstreamerTestCasesLogFile, "GstreamerTestCases.htm" );
+_LIT( KGstreamerTestCasesLogFileWithTitle, "GstreamerTestCases_[%S].htm" );
+
+// FUNCTION PROTOTYPES
+//?type ?function_name(?arg_list);
+
+// FORWARD DECLARATIONS
+//class ?FORWARD_CLASSNAME;
+class CGstreamerTestCases;
+
+// DATA TYPES
+//enum ?declaration
+//typedef ?declaration
+//extern ?data_type;
+
+// CLASS DECLARATION
+
+/**
+* CGstreamerTestCases test class for STIF Test Framework TestScripter.
+* ?other_description_lines
+*
+* @lib ?library
+* @since ?Series60_version
+*/
+NONSHARABLE_CLASS(CGstreamerTestCases) : public CScriptBase
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor.
+ */
+ static CGstreamerTestCases* NewL( CTestModuleIf& aTestModuleIf );
+
+ /**
+ * Destructor.
+ */
+ virtual ~CGstreamerTestCases();
+
+ public: // New functions
+
+ /**
+ * ?member_description.
+ * @since ?Series60_version
+ * @param ?arg1 ?description
+ * @return ?description
+ */
+ //?type ?member_function( ?type ?arg1 );
+
+ public: // Functions from base classes
+
+ /**
+ * From CScriptBase Runs a script line.
+ * @since ?Series60_version
+ * @param aItem Script line containing method name and parameters
+ * @return Symbian OS error code
+ */
+ virtual TInt RunMethodL( CStifItemParser& aItem );
+
+ protected: // New functions
+
+ /**
+ * ?member_description.
+ * @since ?Series60_version
+ * @param ?arg1 ?description
+ * @return ?description
+ */
+ //?type ?member_function( ?type ?arg1 );
+
+ protected: // Functions from base classes
+
+ /**
+ * From ?base_class ?member_description
+ */
+ //?type ?member_function();
+
+ private:
+
+ /**
+ * C++ default constructor.
+ */
+ CGstreamerTestCases( CTestModuleIf& aTestModuleIf );
+
+ /**
+ * By default Symbian 2nd phase constructor is private.
+ */
+ void ConstructL();
+
+ // Prohibit copy constructor if not deriving from CBase.
+ // ?classname( const ?classname& );
+ // Prohibit assigment operator if not deriving from CBase.
+ // ?classname& operator=( const ?classname& );
+
+ /**
+ * Frees all resources allocated from test methods.
+ * @since ?Series60_version
+ */
+ void Delete();
+
+ /**
+ * Test methods are listed below.
+ */
+
+ /**
+ * Example test method.
+ * @since ?Series60_version
+ * @param aItem Script line containing parameters.
+ * @return Symbian OS error code.
+ */
+ virtual TInt ExampleL( CStifItemParser& aItem );
+
+ /**
+ * Method used to log version of test class
+ */
+ void SendTestClassVersion();
+
+ //ADD NEW METHOD DEC HERE
+ //[TestMethods] - Do not remove
+
+ public: // Data
+ // ?one_line_short_description_of_data
+ //?data_declaration;
+
+ protected: // Data
+ // ?one_line_short_description_of_data
+ //?data_declaration;
+
+ private: // Data
+
+ // ?one_line_short_description_of_data
+ //?data_declaration;
+
+ // Reserved pointer for future extension
+ //TAny* iReserved;
+
+ public: // Friend classes
+ //?friend_class_declaration;
+ protected: // Friend classes
+ //?friend_class_declaration;
+ private: // Friend classes
+ //?friend_class_declaration;
+
+ };
+
+#endif // GSTREAMERTESTCASES_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/init/gstreamertestcases_suite4.ini Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,4 @@
+[general]
+logFileName gstreamertestcases_suite4.log
+logPath c:\logs\
+[general_end]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/init/testframework.ini Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,184 @@
+#
+# This is STIFTestFramework initialization file
+# Comment lines start with '#'-character.
+# See STIF TestFramework users guide.doc for instructions
+
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+# Set following test engine settings:
+# - Set Test Reporting mode. TestReportMode's possible values are:
+# + 'Summary': Summary of the tested test cases.
+# + 'Environment': Hardware and software info.
+# + 'TestCases': Test case report.
+# + 'FullReport': Set of all above ones.
+# + Example 'TestReportMode= Summary TestCases'
+#
+# - CreateTestReport setting controls report creation mode
+# + YES, Test report will created.
+# + NO, No Test report.
+#
+# - File path indicates the base path of the test report.
+# - File name indicates the name of the test report.
+#
+# - File format indicates the type of the test report.
+# + TXT, Test report file will be txt type, for example 'TestReport.txt'.
+# + HTML, Test report will be html type, for example 'TestReport.html'.
+#
+# - File output indicates output source of the test report.
+# + FILE, Test report logging to file.
+# + RDEBUG, Test report logging to using rdebug.
+#
+# - File Creation Mode indicates test report overwriting if file exist.
+# + OVERWRITE, Overwrites if the Test report file exist.
+# + APPEND, Continue logging after the old Test report information if
+# report exist.
+# - Sets a device reset module's dll name(Reboot).
+# + If Nokia specific reset module is not available or it is not correct one
+# StifHWResetStub module may use as a template for user specific reset
+# module.
+
+[Engine_Defaults]
+
+TestReportMode= FullReport # Possible values are: 'Empty', 'Summary', 'Environment',
+ 'TestCases' or 'FullReport'
+
+CreateTestReport= YES # Possible values: YES or NO
+
+TestReportFilePath= C:\LOGS\TestFramework\
+TestReportFileName= TestReport_gstreamertestcases_suite4
+
+TestReportFormat= HTML # Possible values: TXT or HTML
+TestReportOutput= FILE # Possible values: FILE or RDEBUG
+TestReportFileCreationMode= OVERWRITE # Possible values: OVERWRITE or APPEND
+
+DeviceResetDllName= StifResetForNokia.dll # e.g. 'StifHWResetStub.dll' for user specific reseting
+
+[End_Defaults]
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+
+
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+# Module configurations start
+# Modules are added between module tags
+# tags. Module name is specified after ModuleName= tag, like
+# ModuleName= XXXXXXXXX
+# Modules might have initialisation file, specified as
+# IniFile= c:\testframework\YYYYYY
+# Modules might have several configuration files, like
+# TestCaseFile= c:\testframework\NormalCases.txt
+# TestCaseFile= c:\testframework\SmokeCases.txt
+# TestCaseFile= c:\testframework\ManualCases.txt
+
+# (TestCaseFile is synonym for old term ConfigFile)
+
+# Following case specifies demo module settings. Demo module
+# does not read any settings from file, so tags
+# IniFile and TestCaseFile are not used.
+# In the simplest case it is enough to specify only the
+# name of the test module when adding new test module
+
+#[New_Module]
+#ModuleName= demomodule
+#[End_Module]
+
+
+[New_Module]
+ModuleName= TestScripter
+TestCaseFile= c:\testframework\gstreamertestcases_suite4.cfg
+IniFile= c:\testframework\gstreamertestcases_suite4.ini
+[End_Module]
+
+# Load testmoduleXXX, optionally with initialization file and/or test case files
+#[New_Module]
+#ModuleName= testmodulexxx
+
+#TestModuleXXX used initialization file
+#IniFile= c:\testframework\init.txt
+
+#TestModuleXXX used configuration file(s)
+#TestCaseFile= c:\testframework\testcases1.cfg
+#TestCaseFile= c:\testframework\testcases2.cfg
+#TestCaseFile= c:\testframework\manualtestcases.cfg
+
+#[End_Module]
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+
+
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+# Set STIFTestFramework logging overwrite parameters for Logger.
+# Hardware and emulator environment logging path and styles can
+# be configured from here to overwrite the Logger's implemented values.
+#
+# Settings description:
+# - Indicates option for creation log directory/directories. If log directory/directories
+# is/are not created by user they will make by software.
+# + YES, Create log directory/directories if not allready exist.
+# + NO, Log directory/directories not created. Only created one is used.
+#
+# - Overwrite emulator path setting.
+# + Example: If 'EmulatorBasePath= C:\LOGS\TestFramework\' and in code is defined
+# Logger's path 'D:\\LOGS\\Module\\' with those definition the path
+# will be 'C:\LOGS\TestFramework\LOGS\Module\'
+#
+# - Overwrite emulator's logging format.
+# + TXT, Log file(s) will be txt type(s), for example 'Module.txt'.
+# + HTML, Log file(s) will be html type(s), for example 'Module.html'.
+#
+# - Overwrited emulator logging output source.
+# + FILE, Logging to file(s).
+# + RDEBUG, Logging to using rdebug(s).
+#
+# - Overwrite hardware path setting (Same description as above in emulator path).
+# - Overwrite hardware's logging format(Same description as above in emulator format).
+# - Overwrite hardware's logging output source(Same description as above in emulator output).
+#
+# - File Creation Mode indicates file overwriting if file exist.
+# + OVERWRITE, Overwrites if file(s) exist.
+# + APPEND, Continue logging after the old logging information if file(s) exist.
+#
+# - Will thread id include to the log filename.
+# + YES, Thread id to log file(s) name, Example filename 'Module_b9.txt'.
+# + NO, No thread id to log file(s), Example filename 'Module.txt'.
+#
+# - Will time stamps include the to log file.
+# + YES, Time stamp added to each line in log file(s). Time stamp is
+# for example'12.Nov.2003 115958 LOGGING INFO'
+# + NO, No time stamp(s).
+#
+# - Will line breaks include to the log file.
+# + YES, Each logging event includes line break and next log event is in own line.
+# + NO, No line break(s).
+#
+# - Will event ranking include to the log file.
+# + YES, Event ranking number added to each line in log file(s). Ranking number
+# depends on environment's tics, for example(includes time stamp also)
+# '012 12.Nov.2003 115958 LOGGING INFO'
+# + NO, No event ranking.
+#
+
+[Logger_Defaults]
+
+#NOTE: If you want to set Logger using next setting(s) remove comment(s)'#'
+
+#CreateLogDirectories= YES # Possible values: YES or NO
+
+#EmulatorBasePath= C:\LOGS\TestFramework\
+#EmulatorFormat= HTML # Possible values: TXT or HTML
+#EmulatorOutput= FILE # Possible values: FILE or RDEBUG
+
+#HardwareBasePath= D:\LOGS\TestFramework\
+#HardwareFormat= HTML # Possible values: TXT or HTML
+#HardwareOutput= FILE # Possible values: FILE or RDEBUG
+
+#FileCreationMode= OVERWRITE # Possible values: OVERWRITE or APPEND
+
+#ThreadIdToLogFile= YES # Possible values: YES or NO
+#WithTimeStamp= YES # Possible values: YES or NO
+#WithLineBreak= YES # Possible values: YES or NO
+#WithEventRanking= YES # Possible values: YES or NO
+
+[End_Logger_Defaults]
+# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+# End of file
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/src/GstreamerTestCases.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,204 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description: This file contains testclass implementation.
+*
+*/
+
+// INCLUDE FILES
+#include <StifTestInterface.h>
+#include "GstreamerTestCases.h"
+#include <SettingServerClient.h>
+
+// EXTERNAL DATA STRUCTURES
+//extern ?external_data;
+
+// EXTERNAL FUNCTION PROTOTYPES
+//extern ?external_function( ?arg_type,?arg_type );
+
+// CONSTANTS
+//const ?type ?constant_var = ?constant;
+
+// MACROS
+//#define ?macro ?macro_def
+
+// LOCAL CONSTANTS AND MACROS
+//const ?type ?constant_var = ?constant;
+//#define ?macro_name ?macro_def
+
+// MODULE DATA STRUCTURES
+//enum ?declaration
+//typedef ?declaration
+
+// LOCAL FUNCTION PROTOTYPES
+//?type ?function_name( ?arg_type, ?arg_type );
+
+// FORWARD DECLARATIONS
+//class ?FORWARD_CLASSNAME;
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// ?function_name ?description.
+// ?description
+// Returns: ?value_1: ?description
+// ?value_n: ?description_line1
+// ?description_line2
+// -----------------------------------------------------------------------------
+//
+/*
+?type ?function_name(
+ ?arg_type arg, // ?description
+ ?arg_type arg) // ?description
+ {
+
+ ?code // ?comment
+
+ // ?comment
+ ?code
+ }
+*/
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::CGstreamerTestCases
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CGstreamerTestCases::CGstreamerTestCases(
+ CTestModuleIf& aTestModuleIf ):
+ CScriptBase( aTestModuleIf )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CGstreamerTestCases::ConstructL()
+ {
+ //Read logger settings to check whether test case name is to be
+ //appended to log file name.
+ RSettingServer settingServer;
+ TInt ret = settingServer.Connect();
+ if(ret != KErrNone)
+ {
+ User::Leave(ret);
+ }
+ // Struct to StifLogger settigs.
+ TLoggerSettings loggerSettings;
+ // Parse StifLogger defaults from STIF initialization file.
+ ret = settingServer.GetLoggerSettings(loggerSettings);
+ if(ret != KErrNone)
+ {
+ User::Leave(ret);
+ }
+ // Close Setting server session
+ settingServer.Close();
+
+ TFileName logFileName;
+
+ if(loggerSettings.iAddTestCaseTitle)
+ {
+ TName title;
+ TestModuleIf().GetTestCaseTitleL(title);
+ logFileName.Format(KGstreamerTestCasesLogFileWithTitle, &title);
+ }
+ else
+ {
+ logFileName.Copy(KGstreamerTestCasesLogFile);
+ }
+
+ iLog = CStifLogger::NewL( KGstreamerTestCasesLogPath,
+ logFileName,
+ CStifLogger::ETxt,
+ CStifLogger::EFile,
+ EFalse );
+
+ SendTestClassVersion();
+ }
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CGstreamerTestCases* CGstreamerTestCases::NewL(
+ CTestModuleIf& aTestModuleIf )
+ {
+ CGstreamerTestCases* self = new (ELeave) CGstreamerTestCases( aTestModuleIf );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+
+// Destructor
+CGstreamerTestCases::~CGstreamerTestCases()
+ {
+
+ // Delete resources allocated from test methods
+ Delete();
+
+ // Delete logger
+ delete iLog;
+
+ }
+
+//-----------------------------------------------------------------------------
+// CGstreamerTestCases::SendTestClassVersion
+// Method used to send version of test class
+//-----------------------------------------------------------------------------
+//
+void CGstreamerTestCases::SendTestClassVersion()
+ {
+ TVersion moduleVersion;
+ moduleVersion.iMajor = TEST_CLASS_VERSION_MAJOR;
+ moduleVersion.iMinor = TEST_CLASS_VERSION_MINOR;
+ moduleVersion.iBuild = TEST_CLASS_VERSION_BUILD;
+
+ TFileName moduleName;
+ moduleName = _L("GstreamerTestCases.dll");
+
+ TBool newVersionOfMethod = ETrue;
+ TestModuleIf().SendTestModuleVersion(moduleVersion, moduleName, newVersionOfMethod);
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// LibEntryL is a polymorphic Dll entry point.
+// Returns: CScriptBase: New CScriptBase derived object
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CScriptBase* LibEntryL(
+ CTestModuleIf& aTestModuleIf ) // Backpointer to STIF Test Framework
+ {
+
+ return ( CScriptBase* ) CGstreamerTestCases::NewL( aTestModuleIf );
+
+ }
+
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/tsrc/gstreamertestcases_suite4/src/GstreamerTestCasesBlocks.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -0,0 +1,237 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Description: This file contains testclass implementation.
+*
+*/
+
+// [INCLUDE FILES] - do not remove
+#include <e32svr.h>
+#include <StifParser.h>
+#include <StifTestInterface.h>
+#include "GstreamerTestCases.h"
+
+// EXTERNAL DATA STRUCTURES
+//extern ?external_data;
+
+// EXTERNAL FUNCTION PROTOTYPES
+//extern ?external_function( ?arg_type,?arg_type );
+
+// CONSTANTS
+//const ?type ?constant_var = ?constant;
+
+// MACROS
+//#define ?macro ?macro_def
+
+// LOCAL CONSTANTS AND MACROS
+//const ?type ?constant_var = ?constant;
+//#define ?macro_name ?macro_def
+
+// MODULE DATA STRUCTURES
+//enum ?declaration
+//typedef ?declaration
+
+// LOCAL FUNCTION PROTOTYPES
+//?type ?function_name( ?arg_type, ?arg_type );
+
+// FORWARD DECLARATIONS
+//class ?FORWARD_CLASSNAME;
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// ?function_name ?description.
+// ?description
+// Returns: ?value_1: ?description
+// ?value_n: ?description_line1
+// ?description_line2
+// -----------------------------------------------------------------------------
+//
+/*
+?type ?function_name(
+ ?arg_type arg, // ?description
+ ?arg_type arg) // ?description
+ {
+
+ ?code // ?comment
+
+ // ?comment
+ ?code
+ }
+*/
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::Delete
+// Delete here all resources allocated and opened from test methods.
+// Called from destructor.
+// -----------------------------------------------------------------------------
+//
+void CGstreamerTestCases::Delete()
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::RunMethodL
+// Run specified method. Contains also table of test mothods and their names.
+// -----------------------------------------------------------------------------
+//
+TInt CGstreamerTestCases::RunMethodL(
+ CStifItemParser& aItem )
+ {
+
+ static TStifFunctionInfo const KFunctions[] =
+ {
+ // Copy this line for every implemented function.
+ // First string is the function name used in TestScripter script file.
+ // Second is the actual implementation member function.
+ ENTRY( "Example", CGstreamerTestCases::ExampleL ),
+ //ADD NEW ENTRY HERE
+ // [test cases entries] - Do not remove
+
+ };
+
+ const TInt count = sizeof( KFunctions ) /
+ sizeof( TStifFunctionInfo );
+
+ return RunInternalL( KFunctions, count, aItem );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::ExampleL
+// Example test method function.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CGstreamerTestCases::ExampleL( CStifItemParser& aItem )
+{
+ TInt err = KErrNone;
+ RTimer timeoutTimer;
+ // Print to UI
+// _LIT( KGstreamerTestCases, "GstreamerTestCases" );
+// _LIT( KExample, "Test case: " );
+// TestModuleIf().Printf( 0, KGstreamerTestCases, KExample );
+ // Print to log file
+
+ TPtrC string[2];
+ TFileName arg;
+ //_LIT( KParam, "Param[%i]: %S" );
+
+ if( aItem.GetNextString ( string[0] ) != KErrNone)
+ {
+ iLog->Log( _L(">> Test cases Not Found") );
+ return -1;
+ }
+ iLog->Log( _L( "Test case Name is : " ) );
+ iLog->Log( string[0] );
+
+ while ( aItem.GetNextString ( string[1] ) == KErrNone )
+ {
+ iLog->Log( string[1] );
+ arg.Append( string[1] );
+ arg.Append( TChar(' ') );
+ }
+
+
+ _LIT( KArg, "Arg: " );
+ iLog->Log( KArg );
+ iLog->Log( arg );
+ RProcess process;
+ err = process.Create( string[0],arg );
+
+ if( !err )
+ {
+
+ if( timeoutTimer.CreateLocal() != KErrNone )
+ {
+ iLog->Log( _L(">> timeoutTimer.CreateLocal failed") );
+ }
+
+ iLog->Log( _L(">> Test cases Started") );
+ TRequestStatus processStatus = KRequestPending;
+ TRequestStatus timerStatus = KRequestPending;
+ process.Logon( processStatus );
+
+ process.Resume();
+ TTimeIntervalMicroSeconds32 timeout = 1 * 60 * 1000000;
+ timeoutTimer.After( timerStatus, timeout );
+
+ while( processStatus == KRequestPending && timerStatus == KRequestPending )
+ {
+ User::WaitForAnyRequest();
+
+ }
+
+ err = process.ExitReason();
+ if( timerStatus != KRequestPending )
+ {
+ err = KErrTimedOut;
+ }
+
+ process.LogonCancel( processStatus );
+ timeoutTimer.Cancel();
+ /// required to complete one of the pending request..
+ User::WaitForAnyRequest();
+
+ process.Kill( KErrNone );
+ process.Close();
+ timeoutTimer.Close();
+ iLog->Log( _L(">> test cases completed") );
+ }
+ else
+ {
+ iLog->Log( _L(">> test cases exe not found") );
+ }
+
+
+ if( err != KErrNone )
+ {
+ iLog->Log( CStifLogger::ERed, _L( "Test cases FAILED!" ) );
+ }
+ else
+ {
+ iLog->Log( CStifLogger::EGreen, _L( "Test cases PASSED!" ) );
+ }
+
+
+ return err;
+}
+
+// -----------------------------------------------------------------------------
+// CGstreamerTestCases::?member_function
+// ?implementation_description
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+/*
+TInt CGstreamerTestCases::?member_function(
+ CItemParser& aItem )
+ {
+
+ ?code
+
+ }
+*/
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// None
+
+// [End of File] - Do not remove
--- a/gstreamer_test_apps/gstplayer/data/GSTPlayer_reg.rss Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/data/GSTPlayer_reg.rss Wed Aug 18 10:04:13 2010 +0300
@@ -32,9 +32,9 @@
* ==============================================================================
*/
-#include "GSTPlayer.rls"
+#include "gstplayer.rls"
#include <appinfo.rh>
-#include <GSTPlayer.rsg>
+#include <gstplayer.rsg>
UID2 KUidAppRegistrationResourceFile
UID3 0xA000017F
--- a/gstreamer_test_apps/gstplayer/data/gstplayer.rss Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/data/gstplayer.rss Wed Aug 18 10:04:13 2010 +0300
@@ -38,9 +38,8 @@
// INCLUDES
#include <eikon.rh>
#include <eikon.rsg>
-#include <Avkon.rsg>
-#include <Avkon.hrh>
-#include <Avkon.rh>
+#include <avkon.hrh>
+#include <avkon.rh>
#include <avkon.loc>
#include <avkon.mbg>
#include <avkonsct.loc>
@@ -49,10 +48,10 @@
#include <CommonDialogs.hrh>
#include <CommonDialogs.rh>
-#include <PathConfiguration.hrh>
+#include <pathconfiguration.hrh>
-#include "GSTPlayer.hrh"
-#include "GSTPlayer.rls"
+#include "gstplayer.hrh"
+#include "gstplayer.rls"
#define KWidth 176
#define KHeight 100
--- a/gstreamer_test_apps/gstplayer/group/gstplayer.mmp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/group/gstplayer.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -45,17 +45,17 @@
SOURCEPATH ../src
SOURCE GSTPlayer.cpp
-SOURCE GSTPlayerApplication.cpp
-SOURCE GSTPlayerAppView.cpp
-SOURCE GSTPlayerAppUi.cpp
-SOURCE GSTPlayerDocument.cpp
+SOURCE GSTPlayerapplication.cpp
+SOURCE GSTPlayerappview.cpp
+SOURCE GSTPlayerappui.cpp
+SOURCE GSTPlayerdocument.cpp
SOURCE RichTextEditor.cpp
SOURCE GlibEventHandler.cpp
SOURCE SymGstreamer.cpp
SOURCEPATH ../data
-START RESOURCE GSTPlayer.rss
+START RESOURCE gstplayer.rss
HEADER
TARGETPATH resource/apps
END //RESOURCE
--- a/gstreamer_test_apps/gstplayer/inc/gstplayerdocument.h Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/inc/gstplayerdocument.h Wed Aug 18 10:04:13 2010 +0300
@@ -35,7 +35,7 @@
#define __GSTPLAYERDOCUMENT_H__
// INCLUDES
-#include <akndoc.h>
+#include <AknDoc.h>
// FORWARD DECLARATIONS
class CGSTPlayerAppUi;
--- a/gstreamer_test_apps/gstplayer/src/GSTPlayer.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/GSTPlayer.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -33,7 +33,7 @@
// INCLUDE FILES
#include <eikstart.h>
-#include "GSTPlayerApplication.h"
+#include "gstplayerapplication.h"
LOCAL_C CApaApplication* NewApplication()
--- a/gstreamer_test_apps/gstplayer/src/GSTPlayerapplication.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/GSTPlayerapplication.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -32,8 +32,8 @@
*/
// INCLUDE FILES
-#include "GSTPlayerDocument.h"
-#include "GSTPlayerApplication.h"
+#include "gstplayerdocument.h"
+#include "gstplayerapplication.h"
// ============================ MEMBER FUNCTIONS ===============================
--- a/gstreamer_test_apps/gstplayer/src/GSTPlayerappui.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/GSTPlayerappui.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -34,18 +34,18 @@
// INCLUDE FILES
#include <avkon.hrh>
#include <aknnotewrappers.h>
-#include <stringloader.h>
-#include <GSTPlayer.rsg>
+#include <StringLoader.h>
+#include <gstplayer.rsg>
#include <CAknMemorySelectionDialog.h>
#include <f32file.h>
#include <s32file.h>
-#include <PathInfo.h>
+#include <pathinfo.h>
#include <gst/gst.h>
-#include "GSTPlayer.pan"
-#include "GSTPlayerAppUi.h"
-#include "GSTPlayerAppView.h"
-#include "GSTPlayer.hrh"
+#include "gstplayer.pan"
+#include "gstplayerappui.h"
+#include "gstplayerappview.h"
+#include "gstplayer.hrh"
#include "GlibEventHandler.h"
#include "gstreamer.h"
--- a/gstreamer_test_apps/gstplayer/src/GSTPlayerappview.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/GSTPlayerappview.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -35,7 +35,7 @@
#include <coemain.h>
#include <stdlib.h>
#include <gst/gst.h>
-#include "GSTPlayerAppView.h"
+#include "gstplayerappview.h"
#include "GlibEventHandler.h"
// ============================ MEMBER FUNCTIONS ===============================
--- a/gstreamer_test_apps/gstplayer/src/GSTPlayerdocument.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/GSTPlayerdocument.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -32,8 +32,8 @@
*/
// INCLUDE FILES
-#include "GSTPlayerAppUi.h"
-#include "GSTPlayerDocument.h"
+#include "gstplayerappui.h"
+#include "gstplayerdocument.h"
// ============================ MEMBER FUNCTIONS ===============================
--- a/gstreamer_test_apps/gstplayer/src/RichTextEditor.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/RichTextEditor.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -24,7 +24,7 @@
* Name : RichTextEditorRTE.cpp
* Part of : VoIP test application.
* Description : Utility for outputting formatted text to the display.
-* Version : %version: 1 %
+* Version : %version: 2 %
* ============================================================================
*/
@@ -32,7 +32,7 @@
#include <barsread.h> // TResourceReader
#include <eikrted.h> // CEikRichTextEditor
#include <txtrich.h> // CRichText
-#include <GSTPlayer.rsg>
+#include <gstplayer.rsg>
#include "RichTextEditor.h"
--- a/gstreamer_test_apps/gstplayer/src/SymGstreamer.cpp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstreamer_test_apps/gstplayer/src/SymGstreamer.cpp Wed Aug 18 10:04:13 2010 +0300
@@ -24,8 +24,8 @@
#include "GlibEventHandler.h"
#include <avkon.hrh>
#include <aknnotewrappers.h>
-#include <stringloader.h>
-#include <GSTPlayer.rsg>
+#include <StringLoader.h>
+#include <gstplayer.rsg>
#include <CAknMemorySelectionDialog.h>
#include <e32base.h>
#include <stdlib.h>
--- a/gstregistrygenerator/group/gstregistrygenerator.mmp Tue Jul 06 14:35:10 2010 +0300
+++ b/gstregistrygenerator/group/gstregistrygenerator.mmp Wed Aug 18 10:04:13 2010 +0300
@@ -42,7 +42,6 @@
VENDORID VID_DEFAULT
USERINCLUDE ../inc
-SYSTEMINCLUDE /epoc32/include
MACRO HAVE_CONFIG_H