comparison src/mediastreamer/msavdecoder.c @ 12024:e67993da8a22

[gaim-migrate @ 14317] I strongly suspect CruiseControl is going to yell at me for this. A voice chat API, GUI + mediastreamer. This is what I'm using for Google Talk. This doesn't actually do anything at all. There's no code in the Jabber plugin yet to use this API (although it Works For Me). All it will do is compile and link. If you're lucky. To build this, you should install oRTP from Linphone, Speex and iLBC (also from linphone, I believe). To not build this, ./configure --disable-vv. Most of the configure.ac and Makefile.am hackery was lifted right out of Linphone with a few modifications. It seems to work if you have everything installed or if you --disable-vv. I haven't really tested not having everything installed and not --disabling-vv. It's kinda funky to include all of mediastreamer in the source tree like this, but linphone doesn't build it as a separate library. I'll probably wind up writing them a patch to build it as a .so so we can link it dynamically instead. This code certainly isn't finished. It'll adapt as I progress on the Google code, but it's certainly of more use here in CVS than in my personal tree. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Wed, 09 Nov 2005 08:07:20 +0000
parents
children
comparison
equal deleted inserted replaced
12023:80faf1ca5280 12024:e67993da8a22
1 /*
2 The mediastreamer library aims at providing modular media processing and I/O
3 for linphone, but also for any telephony application.
4 Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "msavdecoder.h"
22 #include "mscodec.h"
23 extern MSFilter *ms_mpeg_encoder_new();
24 extern MSFilter *ms_mpeg4_encoder_new();
25 extern MSFilter *ms_h263_encoder_new();
26
27
28 MSCodecInfo MPEGinfo={
29 {
30 "MPEG1 codec",
31 0,
32 MS_FILTER_VIDEO_CODEC,
33 ms_mpeg_encoder_new,
34 "This is a MPEG1 codec taken from the ffmpeg project."
35 },
36 ms_mpeg_encoder_new,
37 ms_mpeg_decoder_new,
38 0,
39 0,
40 0, /*bitrate */
41 0, /*sample freq */
42 0,
43 "MPV",
44 1,
45 1
46 };
47
48 MSCodecInfo h263info={
49 {
50 "H263 codec",
51 0,
52 MS_FILTER_VIDEO_CODEC,
53 ms_h263_encoder_new,
54 "This is a H263 codec taken from the ffmpeg project."
55 },
56 ms_h263_encoder_new,
57 ms_h263_decoder_new,
58 0,
59 0,
60 0, /*bitrate */
61 0, /*sample freq */
62 0,
63 "H263",
64 1,
65 1
66 };
67
68 MSCodecInfo MPEG4info={
69 {
70 "MPEG4 codec",
71 0,
72 MS_FILTER_VIDEO_CODEC,
73 ms_mpeg4_encoder_new,
74 "This is a MPEG4 codec taken from the ffmpeg project."
75 },
76 ms_mpeg4_encoder_new,
77 ms_mpeg4_decoder_new,
78 0,
79 0,
80 0, /*bitrate */
81 0, /*sample freq */
82 0,
83 "MP4V-ES",
84 1,
85 1
86 };
87
88
89 void ms_AVCodec_init()
90 {
91 avcodec_init();
92 avcodec_register_all();
93 ms_filter_register((MSFilterInfo*)&h263info);
94 //ms_filter_register((MSFilterInfo*)&MPEG4info);
95 }
96
97
98 static MSAVDecoderClass *ms_avdecoder_class=NULL;
99
100 MSFilter *ms_h263decoder_new()
101 {
102 return ms_AVdecoder_new_with_codec(CODEC_ID_H263);
103 }
104
105 MSFilter *ms_mpeg_decoder_new()
106 {
107 return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG1VIDEO);
108 }
109
110 MSFilter *ms_mpeg4_decoder_new()
111 {
112 return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG4);
113 }
114
115 MSFilter *ms_h263_decoder_new(){
116 return ms_AVdecoder_new_with_codec(CODEC_ID_H263);
117 }
118
119 MSFilter * ms_AVdecoder_new_with_codec(enum CodecID codec_id)
120 {
121 MSAVDecoder *enc;
122
123 enc=g_malloc0(sizeof(MSAVDecoder));
124 if (ms_avdecoder_class==NULL)
125 {
126 ms_avdecoder_class=g_malloc0(sizeof(MSAVDecoderClass));
127 ms_AVdecoder_class_init(ms_avdecoder_class);
128 }
129 MS_FILTER(enc)->klass=(MSFilterClass*)ms_avdecoder_class;
130 ms_AVdecoder_init(enc,avcodec_find_decoder(codec_id));
131 return MS_FILTER(enc);
132 }
133
134
135 void ms_AVdecoder_init(MSAVDecoder *dec, AVCodec *codec)
136 {
137 gint error;
138
139 ms_filter_init(MS_FILTER(dec));
140 MS_FILTER(dec)->inqueues=dec->q_inputs;
141 MS_FILTER(dec)->outqueues=dec->q_outputs;
142 avcodec_get_context_defaults(&dec->av_context);
143 dec->av_codec=codec;
144 dec->av_opened=0;
145 dec->skip_gob=1;
146 dec->obufwrap=NULL;
147 }
148
149 void ms_AVdecoder_class_init(MSAVDecoderClass *klass)
150 {
151 ms_filter_class_init(MS_FILTER_CLASS(klass));
152 ms_filter_class_set_name( MS_FILTER_CLASS(klass),"AVdecoder");
153 MS_FILTER_CLASS(klass)->max_qinputs=MSAVDECODER_MAX_INPUTS;
154 MS_FILTER_CLASS(klass)->max_qoutputs=MSAVDECODER_MAX_INPUTS;
155 MS_FILTER_CLASS(klass)->r_maxgran=0;
156 MS_FILTER_CLASS(klass)->w_maxgran=0;
157 MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_AVdecoder_destroy;
158 MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_AVdecoder_process;
159 }
160
161 void ms_AVdecoder_uninit(MSAVDecoder *dec)
162 {
163 if (dec->obufwrap!=NULL) ms_buffer_destroy(dec->obufwrap);
164 if (dec->av_opened) avcodec_close(&dec->av_context);
165 }
166 void ms_AVdecoder_destroy( MSAVDecoder *obj)
167 {
168 ms_AVdecoder_uninit(obj);
169 g_free(obj);
170 }
171
172 gint ms_AVdecoder_set_format(MSAVDecoder *dec, gchar *fmt)
173 {
174 gint format;
175 if (strcmp(fmt,"YUV420P")==0) format=PIX_FMT_YUV420P;
176 else if (strcmp(fmt,"YUV422")==0) format=PIX_FMT_YUV422;
177 else if (strcmp(fmt,"RGB24")==0) format=PIX_FMT_RGB24;
178 else if (strcmp(fmt,"BGR24")==0) format=PIX_FMT_BGR24;
179 else if (strcmp(fmt,"YUV422P")==0) format=PIX_FMT_YUV422P;
180 else if (strcmp(fmt,"YUV444P")==0) format=PIX_FMT_YUV444P;
181 else {
182 g_warning("ms_AVdecoder_set_format: unsupported format %s.",fmt);
183 return -1;
184 }
185 dec->output_pix_fmt=format;
186 return 0;
187 }
188
189 void ms_AVdecoder_process(MSAVDecoder *r)
190 {
191 AVFrame orig;
192 AVFrame transformed;
193 MSQueue *inq,*outq;
194 MSMessage *inm,*outm;
195 gint error;
196 gint got_picture;
197 gint len;
198 unsigned char *data;
199 AVCodecContext *ctx=&r->av_context;
200 gint gob_num;
201
202 inq=r->q_inputs[0];
203 outq=r->q_outputs[0];
204
205 /* get a picture from the input queue */
206 inm=ms_queue_get(inq);
207 g_return_if_fail(inm!=NULL);
208 if (inm->size > 0)
209 {
210 guint32 *p = inm->data;
211
212 if (!r->av_opened){
213 error=avcodec_open(&r->av_context, r->av_codec);
214 if (error!=0) g_warning("avcodec_open() failed: %i",error);
215 else r->av_opened=1;
216 }
217
218 gob_num = (ntohl(*p) >> 10) & 0x1f;
219 ms_trace("gob %i, size %i", gob_num, inm->size);
220 ms_trace("ms_AVdecoder_process: received %08x %08x", ntohl(p[0]), ntohl(p[1]));
221
222 /* remove H.263 Payload Header */
223 p[0] = htonl( ntohl(p[0]) & 0x0000ffff );
224
225 if (gob_num == 0){
226 if (r->skip_gob == 0)
227 {
228 unsigned char *data = r->buf_compressed;
229 ms_trace("ms_AVdecoder_process: decoding %08x %08x %08x", ntohl(((unsigned int *)data)[0]), ntohl(((unsigned int *)data)[1]), ntohl(((unsigned int *)data)[2]));
230 while (r->buf_size > 0) {
231 len=avcodec_decode_video(&r->av_context,&orig,&got_picture,data,r->buf_size /*inm->size*/);
232 if (len<0) {
233 ms_warning("ms_AVdecoder_process: error %i.",len);
234 break;
235 }
236 if (got_picture) {
237 ms_trace("ms_AVdecoder_process: got_picture: width=%i height=%i fmt=%i",
238 ctx->width,ctx->height,ctx->pix_fmt);
239 /* set the image in the wanted format */
240 outm=ms_message_alloc();
241 if (r->obufwrap==NULL){
242 r->obufwrap=ms_buffer_new(avpicture_get_size(r->output_pix_fmt,ctx->width,ctx->height));
243 r->obufwrap->ref_count++;
244 }
245 ms_message_set_buf(outm,r->obufwrap);
246 avpicture_fill(&transformed,outm->data,r->output_pix_fmt,ctx->width,ctx->height);
247 img_convert(&transformed, r->output_pix_fmt,
248 &orig,ctx->pix_fmt,ctx->width,ctx->height);
249 ms_queue_put(outq,outm);
250 }
251 r->buf_size -= len;
252 data += len;
253 }
254 }
255 else {
256 r->skip_gob = 0;
257 }
258 memcpy(r->buf_compressed, inm->data, inm->size);
259 r->buf_size = inm->size;
260 }
261 else {
262 memcpy(r->buf_compressed + r->buf_size, inm->data, inm->size);
263 r->buf_size += inm->size;
264 }
265 }
266 ms_message_destroy(inm);
267 }
268
269
270 void ms_AVdecoder_set_width(MSAVDecoder *av,gint w)
271 {
272 av->av_context.width=av->width=w;
273 }
274
275 void ms_AVdecoder_set_height(MSAVDecoder *av,gint h)
276 {
277 av->av_context.height=av->height=h;
278 }