Commit 61a50361 authored by Andy Wingo's avatar Andy Wingo

Initial revision

Original commit message from CVS:
Initial revision
parent a2c423bb
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs
codectest
if HAVE_AVIFILE
ARCHSUBDIRS = wincodec
else
ARCHSUBDIRS =
endif
SUBDIRS = $(ARCHSUBDIRS) winaudio
DIST_SUBDIRS = wincodec winaudio
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libgstavimux.la libgstavidecoder.la libgstavidemux.la libgstavitypes.la libgstaviaudiodecoder.la
libgstavidemux_la_SOURCES = gstavidemux.c
libgstavitypes_la_SOURCES = gstavitypes.c
libgstavidecoder_la_SOURCES = gstavidecoder.c
libgstavimux_la_SOURCES = gstavimux.c
libgstaviaudiodecoder_la_SOURCES = gstaviaudiodecoder.c
noinst_HEADERS = gstavidecoder.h gstavimux.h gstavitypes.h gstavidemux.h gstaviaudiodecoder.h
#CFLAGS += -Wall -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math -DNDEBUG
libgstavidecoder_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS)
libgstavidemux_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS)
libgstavitypes_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS)
libgstavimux_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS)
libgstaviaudiodecoder_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS)
EXTRA_DIST = README_win32dll README
noinst_HEADERS = aviaudiodecoder.h
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/avi, auds).. !
! ! ! !
! -src ! !
! / ! (video/avi, 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/avi, ! ! ! ! !
! ! ! auds).. (--------) (------) !
! -sink ! (--------) !
! / ! (video/avi, !avitypes! !
-sink ! ! vids).. ! ! !
! (----------) \-sink src -------------------- (audio/raw)
! (--------) !
(----------------------------------------------------------------)
TODO
----
automatically generate the padtemplates from all possible avi types
found in the registry.
The current win32 dll loader don't work with all versions availble
out there. Make sure to get the windows dll where divxc32.dll has the date
older than 24 january 2000. The 24 january one does currently not work.
/* Gnome-Streamer
* 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.
*/
//#define DEBUG_ENABLED
#include <wine/winbase.h>
#include <wine/winerror.h>
#include <wine/driver.h>
#include <wine/msacm.h>
#define WIN32
#include <gstavidecoder.h>
typedef struct _GstWinLoaderAudioData GstWinLoaderAudioData;
struct _GstWinLoaderAudioData {
guchar ext_info[64];
WAVEFORMATEX wf;
HACMSTREAM srcstream;
GstPad *out;
};
static GstPad *gst_avi_decoder_get_audio_srcpad_MPEG(GstAviDecoder *avi_decoder, guint pad_nr, GstPadTemplate *temp);
static GstPad *gst_avi_decoder_get_audio_srcpad_winloader(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp);
static void gst_avi_decoder_winloader_audio_chain(GstPad *pad, GstBuffer *buf);
GstPad *gst_avi_decoder_get_audio_srcpad(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp)
{
GstPad *newpad;
switch (strf->format) {
case GST_RIFF_WAVE_FORMAT_PCM:
newpad = gst_pad_new("audio_00", GST_PAD_SRC);
gst_pad_set_caps (newpad, gst_caps_new (
"avidecoder_caps",
"audio/raw",
gst_props_new (
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT ((gint)strf->size),
"depth", GST_PROPS_INT ((gint)strf->size),
"rate", GST_PROPS_INT ((gint)strf->rate),
"channels", GST_PROPS_INT ((gint)strf->channels),
NULL)));
avi_decoder->audio_pad[pad_nr] = newpad;
return newpad;
case GST_RIFF_WAVE_FORMAT_MPEGL12:
case GST_RIFF_WAVE_FORMAT_MPEGL3:
return gst_avi_decoder_get_audio_srcpad_MPEG(avi_decoder, pad_nr, temp);
default:
newpad = gst_avi_decoder_get_audio_srcpad_winloader(avi_decoder, pad_nr, strf, temp);
if (newpad) return newpad;
printf("audio format %04x not supported\n", strf->format);
break;
}
return NULL;
}
static GstPad *gst_avi_decoder_get_audio_srcpad_MPEG(GstAviDecoder *avi_decoder, guint pad_nr, GstPadTemplate *temp)
{
GstElement *parse_audio, *decode;
GstPad *srcpad, *sinkpad, *newpad;
parse_audio = gst_elementfactory_make("mp3parse", "parse_audio");
g_return_val_if_fail(parse_audio != NULL, NULL);
decode = gst_elementfactory_make("mpg123", "decode_audio");
g_return_val_if_fail(decode != NULL, NULL);
gst_element_set_state(GST_ELEMENT(gst_object_get_parent(GST_OBJECT(avi_decoder))), GST_STATE_PAUSED);
gst_bin_add(GST_BIN(gst_object_get_parent(GST_OBJECT(avi_decoder))), parse_audio);
gst_bin_add(GST_BIN(gst_object_get_parent(GST_OBJECT(avi_decoder))), decode);
newpad = gst_pad_new("video", GST_PAD_SRC);
gst_pad_set_parent(newpad, GST_OBJECT(avi_decoder));
sinkpad = gst_element_get_pad(parse_audio,"sink");
gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
gst_element_get_pad(decode,"sink"));
gst_pad_set_chain_function (gst_element_get_pad(parse_audio,"src"),
GST_RPAD_CHAINFUNC (gst_element_get_pad(decode,"sink")));
srcpad = gst_element_get_pad(decode,"src");
gst_pad_connect(newpad, sinkpad);
gst_pad_set_name(srcpad, "audio_00");
gst_pad_set_chain_function (newpad, GST_RPAD_CHAINFUNC (sinkpad));
avi_decoder->audio_pad[pad_nr] = newpad;
gst_element_set_state(GST_ELEMENT(gst_object_get_parent(GST_OBJECT(avi_decoder))), GST_STATE_PLAYING);
return srcpad;
}
static GstPad *gst_avi_decoder_get_audio_srcpad_winloader(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp)
{
HRESULT h;
GstWinLoaderAudioData *data;
GstPad *sinkpad, *newpad;
if (!gst_library_load("winloader")) {
gst_info("audiocodecs: could not load support library: 'winloader'\n");
return NULL;
}
gst_info("audiocodecs: winloader loaded\n");
avi_decoder->extra_data = g_malloc0(sizeof(GstWinLoaderAudioData));
data = (GstWinLoaderAudioData *)avi_decoder->extra_data;
memcpy(data->ext_info, strf, sizeof(WAVEFORMATEX));
memset(data->ext_info+18, 0, 32);
if (strf->rate == 0)
return NULL;
data->wf.nChannels=strf->channels;
data->wf.nSamplesPerSec=strf->rate;
data->wf.nAvgBytesPerSec=2*data->wf.nSamplesPerSec*data->wf.nChannels;
data->wf.wFormatTag=strf->format;
data->wf.nBlockAlign=strf->blockalign;
data->wf.wBitsPerSample=strf->av_bps;
data->wf.cbSize=0;
gst_info("audiocodecs: trying to open library %p\n", data);
h = acmStreamOpen(
&data->srcstream,
(HACMDRIVER)NULL,
(WAVEFORMATEX*)data->ext_info,
(WAVEFORMATEX*)&data->wf,
NULL,
0,
0,
0);
if(h != S_OK)
{
if(h == ACMERR_NOTPOSSIBLE) {
printf("audiocodecs:: Unappropriate audio format\n");
}
printf("audiocodecs:: acmStreamOpen error\n");
return NULL;
}
newpad = gst_pad_new("audio", GST_PAD_SINK);
gst_pad_set_parent(newpad, GST_OBJECT(avi_decoder));
gst_pad_set_chain_function(newpad, gst_avi_decoder_winloader_audio_chain);
sinkpad = gst_pad_new("audio_00", GST_PAD_SRC);
gst_pad_set_parent(sinkpad, GST_OBJECT(avi_decoder));
gst_pad_connect(newpad, sinkpad);
gst_pad_set_chain_function (newpad, GST_RPAD_CHAINFUNC (sinkpad));
//gst_pad_connect(newpad, sinkpad);
avi_decoder->audio_pad[pad_nr] = newpad;
data->out = sinkpad;
GST_DEBUG (0,"gst_avi_decoder: pads created\n");
return sinkpad;
}
static void gst_avi_decoder_winloader_audio_chain(GstPad *pad, GstBuffer *buf)
{
GST_DEBUG (0,"gst_avi_decoder: got buffer %08lx %p\n", *(gulong *)GST_BUFFER_DATA(buf), GST_BUFFER_DATA(buf));
gst_buffer_unref(buf);
}
/* Gnome-Streamer
* 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.
*/
//#define GST_DEBUG_ENABLED
#include <string.h>
#include "gstaviaudiodecoder.h"
/* elementfactory information */
static GstElementDetails gst_avi_audio_decoder_details = {
".avi parser",
"Parser/Video",
"Parse a .avi file into audio and video",
VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>\n"
"Wim Taymans <wim.taymans@tvd.be>",
"(C) 1999",
};
/* AviAudioDecoder signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
GST_PADTEMPLATE_FACTORY (sink_templ,
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
"avidecoder_sink",
"video/avi",
"format", GST_PROPS_STRING ("strf_auds")
)
)
GST_PADTEMPLATE_FACTORY (src_audio_templ,
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
"src_audio",
"audio/raw",
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT (16),
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT_RANGE (11025, 44100),
"channels", GST_PROPS_INT_RANGE (1, 2)
)
)
static void gst_avi_audio_decoder_class_init (GstAviAudioDecoderClass *klass);
static void gst_avi_audio_decoder_init (GstAviAudioDecoder *avi_audio_decoder);
static void gst_avi_audio_decoder_chain (GstPad *pad, GstBuffer *buf);
static void gst_avi_audio_decoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static GstElementClass *parent_class = NULL;
//static guint gst_avi_audio_decoder_signals[LAST_SIGNAL] = { 0 };
GType
gst_avi_audio_decoder_get_type(void)
{
static GType avi_audio_decoder_type = 0;
if (!avi_audio_decoder_type) {
static const GTypeInfo avi_audio_decoder_info = {
sizeof(GstAviAudioDecoderClass),
NULL,
NULL,
(GClassInitFunc)gst_avi_audio_decoder_class_init,
NULL,
NULL,
sizeof(GstAviAudioDecoder),
0,
(GInstanceInitFunc)gst_avi_audio_decoder_init,
};
avi_audio_decoder_type = g_type_register_static(GST_TYPE_ELEMENT, "GstAviAudioDecoder", &avi_audio_decoder_info, 0);
}
return avi_audio_decoder_type;
}
static void
gst_avi_audio_decoder_class_init (GstAviAudioDecoderClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref (GST_TYPE_BIN);
gobject_class->get_property = gst_avi_audio_decoder_get_property;
}
static void
gst_avi_audio_decoder_init (GstAviAudioDecoder *avi_audio_decoder)
{
}
static void
gst_avi_audio_decoder_chain (GstPad *pad,
GstBuffer *buf)
{
GstAviAudioDecoder *avi_audio_decoder;
guchar *data;
gulong size;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD(pad));
g_return_if_fail (buf != NULL);
g_return_if_fail (GST_BUFFER_DATA(buf) != NULL);
avi_audio_decoder = GST_AVI_AUDIO_DECODER (gst_pad_get_parent (pad));
GST_DEBUG (0,"gst_avi_audio_decoder_chain: got buffer in %u\n", GST_BUFFER_OFFSET (buf));
g_print ("gst_avi_audio_decoder_chain: got buffer in %u\n", GST_BUFFER_OFFSET (buf));
data = (guchar *)GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
gst_buffer_unref (buf);
}
static void
gst_avi_audio_decoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GstAviAudioDecoder *src;
g_return_if_fail (GST_IS_AVI_AUDIO_DECODER (object));
src = GST_AVI_AUDIO_DECODER (object);
switch(prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
/* create an elementfactory for the avi_audio_decoder element */
factory = gst_elementfactory_new ("aviaudiodecoder",GST_TYPE_AVI_AUDIO_DECODER,
&gst_avi_audio_decoder_details);
g_return_val_if_fail (factory != NULL, FALSE);
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_templ));
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_audio_templ));
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"aviaudiodecoder",
plugin_init
};
/* Gnome-Streamer
* 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_AUDIO_DECODER_H__
#define __GST_AVI_AUDIO_DECODER_H__
#include <config.h>
#include <gst/gst.h>
#include <libs/riff/gstriff.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_AVI_AUDIO_DECODER \
(gst_avi_audio_decoder_get_type())
#define GST_AVI_AUDIO_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVI_AUDIO_DECODER,GstAviAudioDecoder))
#define GST_AVI_AUDIO_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVI_AUDIO_DECODER,GstAviAudioDecoder))
#define GST_IS_AVI_AUDIO_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVI_AUDIO_DECODER))
#define GST_IS_AVI_AUDIO_DECODER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVI_AUDIO_DECODER))
typedef struct _GstAviAudioDecoder GstAviAudioDecoder;
typedef struct _GstAviAudioDecoderClass GstAviAudioDecoderClass;
struct _GstAviAudioDecoder {
GstBin bin;
};
struct _GstAviAudioDecoderClass {
GstBinClass parent_class;
};
GType gst_avi_audio_decoder_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_AVI_AUDIO_DECODER_H__ */
This diff is collapsed.
/* Gnome-Streamer
* 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_DECODER_H__
#define __GST_AVI_DECODER_H__
#include <config.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_AVI_DECODER \
(gst_avi_decoder_get_type())
#define GST_AVI_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVI_DECODER,GstAviDecoder))
#define GST_AVI_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVI_DECODER,GstAviDecoder))
#define GST_IS_AVI_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVI_DECODER))
#define GST_IS_AVI_DECODER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVI_DECODER))
typedef struct _GstAviDecoder GstAviDecoder;
typedef struct _GstAviDecoderClass GstAviDecoderClass;
struct _GstAviDecoder {
GstBin element;
GstElement *demuxer;
gint count;
};
struct _GstAviDecoderClass {
GstBinClass parent_class;
};
GType gst_avi_decoder_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_AVI_DECODER_H__ */
This diff is collapsed.
/* Gnome-Streamer
* 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.
*/