source: mediastreamer2/linphone/mediastreamer2/src/videostream.c @ 213:3ef58e537359

Last change on this file since 213:3ef58e537359 was 213:3ef58e537359, checked in by smorlat <smorlat@…>, 4 years ago

set icon and title on video window too.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@216 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 20.0 KB
Line 
1/*
2mediastreamer2 library - modular sound and video processing and streaming
3Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18*/
19
20#include "mediastreamer2/mediastream.h"
21#include "mediastreamer2/msfilter.h"
22#include "mediastreamer2/msvideo.h"
23#include "mediastreamer2/msrtp.h"
24#include "mediastreamer2/msvideoout.h"
25
26
27#ifdef HAVE_CONFIG_H
28#include "mediastreamer-config.h"
29#endif
30
31extern RtpSession * create_duplex_rtpsession( int locport, bool_t ipv6);
32
33#define MAX_RTP_SIZE    UDP_MAX_SIZE
34
35/* this code is not part of the library itself, it is part of the mediastream program */
36void video_stream_free (VideoStream * stream)
37{
38        if (stream->session!=NULL){
39                rtp_session_unregister_event_queue(stream->session,stream->evq);
40                rtp_session_destroy(stream->session);
41        }
42        if (stream->rtprecv != NULL)
43                ms_filter_destroy (stream->rtprecv);
44        if (stream->rtpsend!=NULL) 
45                ms_filter_destroy (stream->rtpsend);
46        if (stream->source != NULL)
47                ms_filter_destroy (stream->source);
48        if (stream->output != NULL)
49                ms_filter_destroy (stream->output);
50        if (stream->decoder != NULL)
51                ms_filter_destroy (stream->decoder);
52        if (stream->sizeconv != NULL)
53                ms_filter_destroy (stream->sizeconv);
54        if (stream->pixconv!=NULL)
55                ms_filter_destroy(stream->pixconv);
56        if (stream->tee!=NULL)
57                ms_filter_destroy(stream->tee);
58        if (stream->ticker != NULL)
59                ms_ticker_destroy (stream->ticker);
60        if (stream->evq!=NULL)
61                ortp_ev_queue_destroy(stream->evq);
62        ms_free (stream);
63}
64
65/*this function must be called from the MSTicker thread:
66it replaces one filter by another one.
67This is a dirty hack that works anyway.
68It would be interesting to have something that does the job
69simplier within the MSTicker api
70*/
71void video_stream_change_decoder(VideoStream *stream, int payload){
72        RtpSession *session=stream->session;
73        RtpProfile *prof=rtp_session_get_profile(session);
74        PayloadType *pt=rtp_profile_get_payload(prof,payload);
75        if (pt!=NULL){
76                MSFilter *dec=ms_filter_create_decoder(pt->mime_type);
77                if (dec!=NULL){
78                        ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0);
79                        ms_filter_unlink(stream->decoder,0,stream->output,0);
80                        ms_filter_postprocess(stream->decoder);
81                        ms_filter_destroy(stream->decoder);
82                        stream->decoder=dec;
83                        if (pt->recv_fmtp!=NULL)
84                                ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
85                        ms_filter_link (stream->rtprecv, 0, stream->decoder, 0);
86                        ms_filter_link (stream->decoder,0 , stream->output, 0);
87                        ms_filter_preprocess(stream->decoder,stream->ticker);
88                       
89                }else{
90                        ms_warning("No decoder found for %s",pt->mime_type);
91                }
92        }else{
93                ms_warning("No payload defined with number %i",payload);
94        }
95}
96
97static void video_stream_adapt_bitrate(VideoStream *stream, int jitter, float lost){
98        if (stream->encoder!=NULL){
99                if (lost>10){
100                        int bitrate=0;
101                        int new_bitrate;
102                        ms_warning("Remote reports bad receiving experience, trying to reduce bitrate of video encoder.");
103                       
104                        ms_filter_call_method(stream->encoder,MS_FILTER_GET_BITRATE,&bitrate);
105                        if (bitrate==0){
106                                ms_error("Video encoder does not implement MS_FILTER_GET_BITRATE.");
107                                return;
108                        }
109                        if (bitrate>=20000){
110                                new_bitrate=bitrate-10000;
111                                ms_warning("Encoder bitrate reduced from %i to %i b/s.",bitrate,new_bitrate);
112                                ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&new_bitrate);
113                        }else{
114                                ms_warning("Video encoder bitrate already at minimum.");
115                        }
116                       
117                }
118        }
119}
120
121static void video_steam_process_rtcp(VideoStream *stream, mblk_t *m){
122        do{
123                if (rtcp_is_SR(m)){
124                        const report_block_t *rb;
125                        ms_message("video_steam_process_rtcp: receiving RTCP SR");
126                        rb=rtcp_SR_get_report_block(m,0);
127                        if (rb){
128                                unsigned int ij;
129                                float flost;
130                                ij=report_block_get_interarrival_jitter(rb);
131                                flost=100.0*report_block_get_fraction_lost(rb)/256.0;
132                                ms_message("interarrival jitter=%u , lost packets percentage since last report=%f ",ij,flost);
133                                if (stream->adapt_bitrate) video_stream_adapt_bitrate(stream,ij,flost);
134                        }
135                }
136        }while(rtcp_next_packet(m));
137}
138
139void video_stream_iterate(VideoStream *stream){
140       
141        if (stream->output!=NULL)
142                ms_filter_call_method_noarg(stream->output,
143                        MS_VIDEO_OUT_HANDLE_RESIZING);
144       
145        if (stream->evq){
146                OrtpEvent *ev=ortp_ev_queue_get(stream->evq);
147                if (ev!=NULL){
148                        if (ortp_event_get_type(ev)==ORTP_EVENT_RTCP_PACKET_RECEIVED){
149                                OrtpEventData *evd=ortp_event_get_data(ev);
150                                video_steam_process_rtcp(stream,evd->packet);
151                        }
152                        ortp_event_destroy(ev);
153                }
154        }
155}
156
157static void payload_type_changed(RtpSession *session, unsigned long data){
158        VideoStream *stream=(VideoStream*)data;
159        int pt=rtp_session_get_recv_payload_type(stream->session);
160        video_stream_change_decoder(stream,pt);
161}
162
163VideoStream *video_stream_new(int locport, bool_t use_ipv6){
164        VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
165        stream->session=create_duplex_rtpsession(locport,use_ipv6);
166        stream->evq=ortp_ev_queue_new();
167        stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID);
168        rtp_session_register_event_queue(stream->session,stream->evq);
169        stream->sent_vsize.width=MS_VIDEO_SIZE_CIF_W;
170        stream->sent_vsize.height=MS_VIDEO_SIZE_CIF_H;
171        return stream;
172}
173
174void video_stream_set_sent_video_size(VideoStream *stream, MSVideoSize vsize){
175        stream->sent_vsize=vsize;
176}
177
178void video_stream_set_relay_session_id(VideoStream *stream, const char *id){
179        ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id);
180}
181
182void video_stream_enable_self_view(VideoStream *stream, bool_t val){
183        MSFilter *out=stream->output;
184        stream->corner=val ? 0 : -1;
185        if (out){
186                ms_filter_call_method(out,MS_VIDEO_OUT_SET_CORNER,&stream->corner);
187        }
188}
189
190void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno){
191        s->adapt_bitrate=yesno;
192}
193
194int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport,
195        int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam){
196        PayloadType *pt;
197        RtpSession *rtps=stream->session;
198        MSPixFmt format;
199        MSVideoSize vsize,cam_vsize,disp_size;
200        float fps=15;
201        int tmp;
202        JBParameters jbp;
203        const int socket_buf_size=2000000;
204
205        pt=rtp_profile_get_payload(profile,payload);
206        if (pt==NULL){
207                ms_error("videostream.c: undefined payload type.");
208                return -1;
209        }
210        stream->encoder=ms_filter_create_encoder(pt->mime_type);
211        stream->decoder=ms_filter_create_decoder(pt->mime_type);
212        if ((stream->encoder==NULL) || (stream->decoder==NULL)){
213                /* big problem: we have not a registered codec for this payload...*/
214                ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_type);
215                return -1;
216        }
217       
218        rtp_session_set_profile(rtps,profile);
219        if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port);
220        rtp_session_set_payload_type(rtps,payload);
221        rtp_session_set_jitter_compensation(rtps,jitt_comp);
222
223        rtp_session_signal_connect(stream->session,"payload_type_changed",
224                        (RtpCallback)payload_type_changed,(unsigned long)stream);
225
226        rtp_session_set_recv_buf_size(stream->session,MAX_RTP_SIZE);
227
228        rtp_session_get_jitter_buffer_params(stream->session,&jbp);
229        jbp.max_packets=1000;//needed for high resolution video
230        rtp_session_set_jitter_buffer_params(stream->session,&jbp);
231
232        rtp_session_set_rtp_socket_recv_buffer_size(stream->session,socket_buf_size);
233        rtp_session_set_rtp_socket_send_buffer_size(stream->session,socket_buf_size);
234
235        /* creates two rtp filters to recv send streams (remote part) */
236        if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session);
237       
238        stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID);
239        ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session);
240
241        /* creates the filters */
242        stream->source = ms_web_cam_create_reader(cam);
243        stream->tee = ms_filter_new(MS_TEE_ID);
244        stream->output=ms_filter_new(MS_VIDEO_OUT_ID);
245        stream->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);
246       
247        if (pt->normal_bitrate>0){
248                ms_message("Limiting bitrate of video encoder to %i bits/s",pt->normal_bitrate);
249                ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
250        }
251        /* set parameters to the encoder and decoder*/
252        if (pt->send_fmtp){
253                ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
254                ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
255        }
256        ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
257        vsize=ms_video_size_min(vsize,stream->sent_vsize);
258        ms_filter_call_method(stream->encoder,MS_FILTER_SET_VIDEO_SIZE,&vsize);
259        ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps);
260        ms_message("Setting vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps);
261        /* configure the filters */
262        ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
263        ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
264
265        /* get the output format for webcam reader */
266        ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
267        if (format==MS_MJPEG){
268                stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
269        }else{
270                stream->pixconv = ms_filter_new(MS_PIX_CONV_ID);
271                /*set it to the pixconv */
272                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);
273
274                ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&cam_vsize);
275       
276                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&cam_vsize);
277        }
278
279        ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
280
281        /*force the decoder to output YUV420P */
282        format=MS_YUV420P;
283        ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format);
284
285        disp_size.width=MS_VIDEO_SIZE_CIF_W;
286        disp_size.height=MS_VIDEO_SIZE_CIF_H;
287        tmp=1;
288        ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
289        ms_filter_call_method(stream->output,MS_VIDEO_OUT_AUTO_FIT,&tmp);
290        ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
291        ms_filter_call_method(stream->output,MS_VIDEO_OUT_SET_CORNER,&stream->corner);
292
293        if (pt->recv_fmtp!=NULL)
294                ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
295
296        /* and then connect all */
297        ms_filter_link (stream->source, 0, stream->pixconv, 0);
298        ms_filter_link (stream->pixconv, 0, stream->sizeconv, 0);
299        ms_filter_link (stream->sizeconv, 0, stream->tee, 0);
300        ms_filter_link (stream->tee, 0 ,stream->encoder, 0 );
301        ms_filter_link (stream->encoder,0, stream->rtpsend,0);
302       
303        ms_filter_link (stream->rtprecv, 0, stream->decoder, 0);
304        ms_filter_link (stream->decoder,0 , stream->output, 0);
305        /* the source video must be send for preview */
306        ms_filter_link(stream->tee,1,stream->output,1);
307
308        /* create the ticker */
309        stream->ticker = ms_ticker_new(); 
310        /* attach it the graph */
311        ms_ticker_attach (stream->ticker, stream->source);
312        return 0;
313}
314
315void video_stream_send_vfu(VideoStream *stream){
316        if (stream->encoder)
317                ms_filter_call_method_noarg(stream->encoder,MS_FILTER_REQ_VFU);
318}
319
320void
321video_stream_stop (VideoStream * stream)
322{
323        if (stream->ticker){
324                ms_ticker_detach(stream->ticker,stream->source);
325       
326                rtp_stats_display(rtp_session_get_stats(stream->session),"Video session's RTP statistics");
327               
328                ms_filter_unlink(stream->source,0,stream->pixconv,0);
329                ms_filter_unlink (stream->pixconv, 0, stream->sizeconv, 0);
330                ms_filter_unlink (stream->sizeconv, 0, stream->tee, 0);
331                ms_filter_unlink(stream->tee,0,stream->encoder,0);
332                ms_filter_unlink(stream->encoder, 0, stream->rtpsend,0);
333                ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0);
334                ms_filter_unlink(stream->decoder,0,stream->output,0);
335                ms_filter_unlink(stream->tee,1,stream->output,1);
336        }
337        video_stream_free (stream);
338}
339
340
341void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const char *tool){
342        if (st->session!=NULL){
343                rtp_session_set_source_description(st->session,cname,NULL,NULL,NULL,NULL,tool,
344                                                                                        "This is free software (GPL) !");
345        }
346}
347
348unsigned long video_stream_get_native_window_id(VideoStream *stream){
349        unsigned long id;
350        if (stream->output){
351                if (ms_filter_call_method(stream->output,MS_VIDEO_OUT_GET_NATIVE_WINDOW_ID,&id)==0)
352                        return id;
353        }
354        return 0;
355}
356
357
358VideoStream * video_preview_start(MSWebCam *device, MSVideoSize disp_size){
359        VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
360        MSVideoSize vsize=disp_size;
361        MSPixFmt format;
362        float fps=29.97;
363        int mirroring=1;
364
365        /* creates the filters */
366        stream->source = ms_web_cam_create_reader(device);
367        stream->output = ms_filter_new(MS_VIDEO_OUT_ID);
368
369
370        /* configure the filters */
371        ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
372        ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
373        ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
374        ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
375        if (format==MS_MJPEG){
376                stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
377        }else{
378                stream->pixconv=ms_filter_new(MS_PIX_CONV_ID);
379                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);
380                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
381        }
382
383        format=MS_YUV420P;
384        ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
385        ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
386        ms_filter_call_method(stream->output,MS_VIDEO_OUT_ENABLE_MIRRORING,&mirroring);
387        /* and then connect all */
388
389        ms_filter_link(stream->source,0, stream->pixconv,0);
390        ms_filter_link(stream->pixconv, 0, stream->output, 0);
391
392        /* create the ticker */
393        stream->ticker = ms_ticker_new(); 
394        ms_ticker_attach (stream->ticker, stream->source);
395        return stream;
396}
397
398void video_preview_stop(VideoStream *stream){
399        ms_ticker_detach(stream->ticker, stream->source);
400        ms_filter_unlink(stream->source,0,stream->pixconv,0);
401        ms_filter_unlink(stream->pixconv,0,stream->output,0);
402       
403        video_stream_free(stream);
404}
405
406
407int video_stream_send_only_start(VideoStream* stream, RtpProfile *profile, const char *remip, int remport,
408        int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *device){
409        PayloadType *pt;
410        MSPixFmt format;
411        MSVideoSize vsize;
412        RtpSession *rtps=stream->session;
413        float fps=15;
414       
415        vsize.width=MS_VIDEO_SIZE_CIF_W;
416        vsize.height=MS_VIDEO_SIZE_CIF_H;
417
418        rtp_session_set_profile(rtps,profile);
419        if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port);
420        rtp_session_set_payload_type(rtps,payload);
421        rtp_session_set_jitter_compensation(rtps,jitt_comp);
422       
423        /* creates rtp filter to send streams (remote part) */
424        rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE);
425        stream->rtpsend =ms_filter_new(MS_RTP_SEND_ID);
426        if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session);
427
428        /* creates the filters */
429        pt=rtp_profile_get_payload(profile,payload);
430        if (pt==NULL){
431                video_stream_free(stream);
432                ms_error("videostream.c: undefined payload type.");
433                return -1;
434        }
435        stream->encoder=ms_filter_create_encoder(pt->mime_type);
436        if ((stream->encoder==NULL)){
437                /* big problem: we have not a registered codec for this payload...*/
438                video_stream_free(stream);
439                ms_error("videostream.c: No codecs available for payload %i.",payload);
440                return -1;
441        }
442
443        /* creates the filters */
444        stream->source = ms_web_cam_create_reader(device);
445        stream->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);
446
447        /* configure the filters */
448        if (pt->send_fmtp)
449                ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
450        ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
451        ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps);
452        ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
453
454        ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
455        ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
456       
457        /* get the output format for webcam reader */
458        ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
459        /*set it to the pixconv */
460
461        /* bug fix from AMD: What about MJPEG mode???*/
462        if (format==MS_MJPEG){
463                stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
464        }else{
465                stream->pixconv=ms_filter_new(MS_PIX_CONV_ID);
466                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);
467
468                ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
469                ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
470        }
471
472        ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
473        ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
474       
475        ms_message("vsize=%ix%i, fps=%f, send format: %s, capture format: %d, bitrate: %d",
476                        vsize.width,vsize.height,fps,pt->send_fmtp,format, pt->normal_bitrate);
477
478        /* and then connect all */
479        ms_filter_link (stream->source, 0, stream->pixconv, 0);
480        ms_filter_link (stream->pixconv, 0, stream->sizeconv, 0);
481        ms_filter_link (stream->sizeconv, 0, stream->encoder, 0);
482        ms_filter_link (stream->encoder,0, stream->rtpsend,0);
483
484        /* create the ticker */
485        stream->ticker = ms_ticker_new(); 
486        /* attach it the graph */
487        ms_ticker_attach (stream->ticker, stream->source);
488        return 0;
489}
490
491void video_stream_send_only_stop(VideoStream *stream){
492        if (stream->ticker){
493                ms_ticker_detach (stream->ticker, stream->source);
494                ms_filter_unlink(stream->source,0,stream->pixconv,0);
495                ms_filter_unlink (stream->pixconv, 0, stream->sizeconv, 0);
496                ms_filter_unlink (stream->sizeconv, 0, stream->encoder, 0);
497                ms_filter_unlink(stream->encoder,0,stream->rtpsend,0);
498        }
499        video_stream_free(stream);
500}
501
502int video_stream_recv_only_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport,int payload, int jitt_comp){
503        PayloadType *pt;
504        MSPixFmt format;
505        MSVideoSize vsize;
506        RtpSession *rtps=stream->session;
507       
508        vsize.width=MS_VIDEO_SIZE_CIF_W;
509        vsize.height=MS_VIDEO_SIZE_CIF_H;
510
511        rtp_session_set_profile(rtps,profile);
512        if (remport>0) rtp_session_set_remote_addr(rtps,remip,remport);
513        rtp_session_set_payload_type(rtps,payload);
514        rtp_session_set_jitter_compensation(rtps,jitt_comp);
515       
516        /* creates rtp filters to recv streams */
517        rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE);
518        stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID);
519        ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps);
520
521        /* creates the filters */
522        pt=rtp_profile_get_payload(profile,payload);
523        if (pt==NULL){
524                ms_error("videostream.c: undefined payload type.");
525                return -1;
526        }
527        stream->decoder=ms_filter_create_decoder(pt->mime_type);
528        if (stream->decoder==NULL){
529                /* big problem: we have not a registered codec for this payload...*/
530                ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_type);
531                return -1;
532        }
533        stream->output=ms_filter_new(MS_VIDEO_OUT_ID);
534
535        /*force the decoder to output YUV420P */
536        format=MS_YUV420P;
537        /*ask the size-converter to always output CIF */
538        vsize.width=MS_VIDEO_SIZE_CIF_W;
539        vsize.height=MS_VIDEO_SIZE_CIF_H;
540        ms_message("Setting output vsize=%ix%i",vsize.width,vsize.height);
541       
542        ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format);
543        ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
544        ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize);
545
546        if (pt->recv_fmtp!=NULL) {
547                ms_message("pt->recv_fmtp: %s", pt->recv_fmtp);
548                ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
549        }
550
551        /* and then connect all */
552        ms_filter_link (stream->rtprecv, 0, stream->decoder, 0);
553        ms_filter_link (stream->decoder,0 , stream->output, 0);
554
555        /* create the ticker */
556        stream->ticker = ms_ticker_new(); 
557        /* attach it the graph */
558        ms_ticker_attach (stream->ticker, stream->rtprecv);
559        return 0;
560}
561
562void video_stream_recv_only_stop (VideoStream * stream){
563        if (stream->ticker!=NULL){
564                ms_ticker_detach(stream->ticker, stream->rtprecv);
565                rtp_stats_display(rtp_session_get_stats(stream->session),"Video session's RTP statistics");
566                ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0);
567                ms_filter_unlink(stream->decoder,0,stream->output,0);
568        }
569        video_stream_free (stream);
570}
571
Note: See TracBrowser for help on using the repository browser.