Plugins cleanup:
[platform/upstream/gstreamer.git] / gst / avi / audiocodecs.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21
22 /*#define DEBUG_ENABLED */
23
24
25 #include <wine/winbase.h>
26 #include <wine/winerror.h>
27 #include <wine/driver.h>
28 #include <wine/msacm.h>
29 #define WIN32
30 #include <gstavidecoder.h>
31
32 typedef struct _GstWinLoaderAudioData GstWinLoaderAudioData;
33
34 struct _GstWinLoaderAudioData {
35   guchar ext_info[64];
36   WAVEFORMATEX wf;
37   HACMSTREAM srcstream;
38   GstPad *out;
39 };
40
41
42 static GstPad *gst_avi_decoder_get_audio_srcpad_MPEG(GstAviDecoder *avi_decoder, guint pad_nr, GstPadTemplate *temp);
43 static GstPad *gst_avi_decoder_get_audio_srcpad_winloader(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp);
44 static void gst_avi_decoder_winloader_audio_chain(GstPad *pad, GstBuffer *buf);
45
46 GstPad *gst_avi_decoder_get_audio_srcpad(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp) 
47 {
48   GstPad *newpad;
49
50   switch (strf->format) {
51     case GST_RIFF_WAVE_FORMAT_PCM:
52       newpad = gst_pad_new("audio_00", GST_PAD_SRC);
53       gst_pad_try_set_caps (newpad, 
54                             GST_CAPS_NEW (
55                               "avidecoder_caps",
56                               "audio/raw",
57                                  "format",      GST_PROPS_STRING ("int"),
58                                  "law",         GST_PROPS_INT (0),
59                                   "endianness", GST_PROPS_INT (G_BYTE_ORDER),
60                                   "signed",     GST_PROPS_BOOLEAN (TRUE),
61                                   "width",      GST_PROPS_INT ((gint)strf->size),
62                                   "depth",      GST_PROPS_INT ((gint)strf->size),
63                                   "rate",       GST_PROPS_INT ((gint)strf->rate),
64                                   "channels",   GST_PROPS_INT ((gint)strf->channels)
65                             ));
66
67       avi_decoder->audio_pad[pad_nr] = newpad;
68       return newpad;
69     case GST_RIFF_WAVE_FORMAT_MPEGL12:
70     case GST_RIFF_WAVE_FORMAT_MPEGL3:
71       return gst_avi_decoder_get_audio_srcpad_MPEG(avi_decoder, pad_nr, temp);
72     default:
73       newpad = gst_avi_decoder_get_audio_srcpad_winloader(avi_decoder, pad_nr, strf, temp); 
74       if (newpad) return newpad;
75       printf("audio format %04x not supported\n", strf->format);
76       break;
77   }
78   return NULL;
79 }
80
81 static GstPad *gst_avi_decoder_get_audio_srcpad_MPEG(GstAviDecoder *avi_decoder, guint pad_nr, GstPadTemplate *temp) 
82 {
83   GstElement *parse_audio, *decode;
84   GstPad *srcpad, *sinkpad, *newpad;
85
86   parse_audio = gst_element_factory_make("mp3parse", "parse_audio");
87   g_return_val_if_fail(parse_audio != NULL, NULL);
88   decode = gst_element_factory_make("mpg123", "decode_audio");
89   g_return_val_if_fail(decode != NULL, NULL);
90
91   gst_element_set_state(GST_ELEMENT(gst_object_get_parent(GST_OBJECT(avi_decoder))), GST_STATE_PAUSED);
92
93   gst_bin_add(GST_BIN(gst_object_get_parent(GST_OBJECT(avi_decoder))), parse_audio);
94   gst_bin_add(GST_BIN(gst_object_get_parent(GST_OBJECT(avi_decoder))), decode);
95
96   newpad = gst_pad_new("video", GST_PAD_SRC);
97   gst_pad_set_parent(newpad, GST_ELEMENT(avi_decoder));
98
99   sinkpad = gst_element_get_pad(parse_audio,"sink");
100   gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
101                   gst_element_get_pad(decode,"sink"));
102   gst_pad_set_chain_function (gst_element_get_pad(parse_audio,"src"),
103                               GST_RPAD_CHAINFUNC (gst_element_get_pad(decode,"sink")));
104   srcpad = gst_element_get_pad(decode,"src");
105
106   gst_pad_connect(newpad, sinkpad);
107   gst_pad_set_name(srcpad, "audio_00");
108   gst_pad_set_chain_function (newpad, GST_RPAD_CHAINFUNC (sinkpad));
109
110   avi_decoder->audio_pad[pad_nr] = newpad;
111   gst_element_set_state(GST_ELEMENT(gst_object_get_parent(GST_OBJECT(avi_decoder))), GST_STATE_PLAYING);
112
113   return srcpad;
114 }
115
116 static GstPad *gst_avi_decoder_get_audio_srcpad_winloader(GstAviDecoder *avi_decoder, guint pad_nr, gst_riff_strf_auds *strf, GstPadTemplate *temp) 
117 {
118   HRESULT h;
119   GstWinLoaderAudioData *data;
120   GstPad *sinkpad, *newpad;
121
122   if (!gst_library_load("winloader")) {
123     gst_info("audiocodecs: could not load support library: 'winloader'\n");
124     return NULL;
125   }
126   gst_info("audiocodecs: winloader loaded\n");
127
128   avi_decoder->extra_data = g_malloc0(sizeof(GstWinLoaderAudioData));
129
130   data = (GstWinLoaderAudioData *)avi_decoder->extra_data;
131
132   memcpy(data->ext_info, strf, sizeof(WAVEFORMATEX));
133   memset(data->ext_info+18, 0, 32);
134
135   if (strf->rate == 0) 
136     return NULL;
137
138   data->wf.nChannels=strf->channels;
139   data->wf.nSamplesPerSec=strf->rate;
140   data->wf.nAvgBytesPerSec=2*data->wf.nSamplesPerSec*data->wf.nChannels;
141   data->wf.wFormatTag=strf->format;
142   data->wf.nBlockAlign=strf->blockalign;
143   data->wf.wBitsPerSample=strf->av_bps;
144   data->wf.cbSize=0;
145
146   gst_info("audiocodecs: trying to open library %p\n", data);
147   h = acmStreamOpen(
148            &data->srcstream,
149            (HACMDRIVER)NULL,       
150            (WAVEFORMATEX*)data->ext_info,  
151            (WAVEFORMATEX*)&data->wf,  
152            NULL,  
153            0,     
154            0,     
155            0);
156
157   if(h != S_OK)
158   {
159      if(h == ACMERR_NOTPOSSIBLE) {
160        printf("audiocodecs:: Unappropriate audio format\n");
161      }
162      printf("audiocodecs:: acmStreamOpen error\n");
163      return NULL;
164   }
165
166   newpad = gst_pad_new("audio", GST_PAD_SINK);
167   gst_pad_set_parent(newpad, GST_ELEMENT(avi_decoder));
168   gst_pad_set_chain_function(newpad, gst_avi_decoder_winloader_audio_chain);
169
170   sinkpad = gst_pad_new("audio_00", GST_PAD_SRC);
171   gst_pad_set_parent(sinkpad, GST_ELEMENT(avi_decoder));
172   gst_pad_connect(newpad, sinkpad);
173   gst_pad_set_chain_function (newpad, GST_RPAD_CHAINFUNC (sinkpad));
174
175   /*gst_pad_connect(newpad, sinkpad); */
176   avi_decoder->audio_pad[pad_nr] = newpad;
177
178   data->out = sinkpad;
179
180   GST_DEBUG (0,"gst_avi_decoder: pads created");
181   return sinkpad;
182 }
183
184 static void gst_avi_decoder_winloader_audio_chain(GstPad *pad, GstBuffer *buf) 
185 {
186
187   GST_DEBUG (0,"gst_avi_decoder: got buffer %08lx %p", *(gulong *)GST_BUFFER_DATA(buf), GST_BUFFER_DATA(buf));
188   gst_buffer_unref(buf);  
189 }