Commit 2055dec5 authored by Yann Diorcet's avatar Yann Diorcet

Add generic PLC

parent 8f038bf3
......@@ -133,7 +133,8 @@ typedef enum MSFilterId{
MS_L16_ENC_ID,
MS_L16_DEC_ID,
MS_OSX_GL_DISPLAY_ID,
MS_GLXVIDEO_ID
MS_GLXVIDEO_ID,
MS_GENERIC_PLC_ID
} MSFilterId;
......
......@@ -56,6 +56,7 @@ struct _AudioStream
MSFilter *rtpsend;
MSFilter *dtmfgen;
MSFilter *dtmfgen_rtp;
MSFilter *plc;
MSFilter *ec;/*echo canceler*/
MSFilter *volsend,*volrecv; /*MSVolumes*/
MSFilter *read_resampler;
......
......@@ -557,6 +557,7 @@ enum _MSFilterInterfaceId{
MSFilterEchoCancellerInterface,
MSFilterVideoDecoderInterface,
MSFilterVideoCaptureInterface,
MSFilterDecoderInterface,
};
typedef enum _MSFilterInterfaceId MSFilterInterfaceId;
......
......@@ -139,4 +139,8 @@ typedef enum _MSPlayerState MSPlayerState;
#define MS_VIDEO_CAPTURE_SET_DEVICE_ORIENTATION \
MS_FILTER_METHOD(MSFilterVideoCaptureInterface,0,int)
/** Interface definitions for decoder */
#define MS_DECODER_HAVE_PLC \
MS_FILTER_METHOD(MSFilterDecoderInterface,0,int)
#endif
......@@ -61,7 +61,8 @@ libmediastreamer_la_SOURCES= mscommon.c $(GITVERSION_FILE) \
audioconference.c \
bitratedriver.c \
qosanalyzer.c \
bitratecontrol.c
bitratecontrol.c \
genericplc.c
#dummy c++ file to force libtool to use c++ linking (because of msdscap-mingw.cc)
nodist_EXTRA_libmediastreamer_la_SOURCES = dummy.cxx
......
......@@ -476,6 +476,17 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
}
stream->qi=ms_quality_indicator_new(stream->session);
/* Create PLC */
int decoder_have_plc = 0;
if (ms_filter_call_method(stream->decoder,MS_DECODER_HAVE_PLC,&decoder_have_plc)!=0) {
ms_warning("MS_DECODER_HAVE_PLC function not implemented by the decoder: enable default plc");
}
if(decoder_have_plc == 0)
stream->plc=ms_filter_new(MS_GENERIC_PLC_ID);
if (stream->plc)
ms_filter_call_method(stream->plc,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
/* create ticker */
if (stream->ticker==NULL) start_ticker(stream);
else{
......@@ -504,6 +515,8 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_connection_helper_start(&h);
ms_connection_helper_link(&h,stream->rtprecv,-1,0);
ms_connection_helper_link(&h,stream->decoder,0,0);
if(stream->plc)
ms_connection_helper_link(&h, stream->plc,0,0);
ms_connection_helper_link(&h,stream->dtmfgen,0,0);
if (stream->volrecv)
ms_connection_helper_link(&h,stream->volrecv,0,0);
......
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2011 Yann Diorcet(yann.diorcet@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/mscodecutils.h>
#include <mediastreamer2/msticker.h>
/*filter common method*/
typedef struct {
MSConcealerContext* concealer;
int rate;
} generic_plc_struct;
const static unsigned int MAX_PLC_COUNT = UINT32_MAX;
static void generic_plc_init(MSFilter *f) {
generic_plc_struct *mgps = (generic_plc_struct*) ms_new0(generic_plc_struct, 1);
mgps->concealer = ms_concealer_context_new(MAX_PLC_COUNT);
f->data = mgps;
}
static void generic_plc_process(MSFilter *f) {
generic_plc_struct *mgps=(generic_plc_struct*)f->data;
unsigned int buff_size =mgps->rate*sizeof(int16_t)*f->ticker->interval/1000;
mblk_t *m;
while((m=ms_queue_get(f->inputs[0]))!=NULL){
ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, 20, TRUE);
ms_queue_put(f->outputs[0], m);
}
if (ms_concealer_context_is_concealement_required(mgps->concealer, f->ticker->time)) {
m = allocb(buff_size, 0);
memset(m->b_wptr, 0, buff_size);
m->b_wptr += buff_size;
ms_queue_put(f->outputs[0], m);
ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, f->ticker->interval, FALSE);
}
}
static void generic_plc_unit(MSFilter *f) {
generic_plc_struct *mgps = (generic_plc_struct*) f->data;
ms_concealer_context_destroy(mgps->concealer);
ms_free(mgps);
}
static int generic_plc_get_sr(MSFilter *f, void *arg){
generic_plc_struct *s=(generic_plc_struct*)f->data;
((int*)arg)[0]=s->rate;
return 0;
}
static int generic_plc_set_sr(MSFilter *f, void *arg){
generic_plc_struct *s=(generic_plc_struct*)f->data;
s->rate=((int*)arg)[0];
return 0;
}
static MSFilterMethod generic_plc_methods[] = {
{ MS_FILTER_SET_SAMPLE_RATE , generic_plc_set_sr },
{ MS_FILTER_GET_SAMPLE_RATE , generic_plc_get_sr },
{ 0 , NULL }
};
#ifdef _MSC_VER
MSFilterDesc ms_genericplc_desc= {
MS_GENERIC_PLC_ID,
"MSGenericPLC",
N_("Generic PLC."),
MS_FILTER_OTHER,
NULL,
1,
1,
generic_plc_init,
NULL,
generic_plc_process,
NULL,
generic_plc_unit,
generic_plc_methods
};
#else
MSFilterDesc ms_genericplc_desc = {
.id = MS_GENERIC_PLC_ID,
.name = "MSGenericPLC",
.text = N_("Generic PLC."),
.category = MS_FILTER_OTHER,
.ninputs = 1,
.noutputs = 1,
.init = generic_plc_init,
.process = generic_plc_process,
.uninit = generic_plc_unit,
.flags = MS_FILTER_IS_PUMP,
.methods = generic_plc_methods
};
#endif
MS_FILTER_DESC_EXPORT(ms_genericplc_desc)
......@@ -601,10 +601,17 @@ static void dec_process(MSFilter *f){
if (bits_initd) speex_bits_destroy(&bits);
}
static int dec_have_plc(MSFilter *f, void *arg)
{
*((int *)arg) = 1;
return 0;
}
static MSFilterMethod dec_methods[]={
{ MS_FILTER_SET_SAMPLE_RATE , dec_set_sr },
{ MS_FILTER_GET_SAMPLE_RATE , dec_get_sr },
{ MS_FILTER_ADD_FMTP , dec_add_fmtp },
{ MS_FILTER_ADD_FMTP , dec_add_fmtp },
{ MS_DECODER_HAVE_PLC , dec_have_plc },
{ 0 , NULL }
};
......
......@@ -112,6 +112,7 @@ typedef struct _MediastreamDatas {
char* srtp_local_master_key;
char* srtp_remote_master_key;
int netsim_bw;
int netsim_lossrate;
float zoom;
float zoom_cx, zoom_cy;
......@@ -177,6 +178,7 @@ const char *usage="mediastream --local <port> --remote <ip:port> \n"
"[ --video-windows-id <video surface:preview surface>]\n"
"[ --srtp <local master_key> <remote master_key> (enable srtp, master key is generated if absent from comand line)\n"
"[ --netsim-bandwidth <bandwidth limit in bits/s> (simulates a network download bandwidth limit)\n"
"[ --netsim-lossrate <0-100> (simulates a network lost rate)\n"
"[ --zoom zoomfactor]\n"
;
......@@ -422,7 +424,18 @@ bool_t parse_args(int argc, char** argv, MediastreamDatas* out) {
} else if (strcmp(argv[i],"--netsim-bandwidth")==0){
i++;
out->netsim_bw=atoi(argv[i]);
}else if (strcmp(argv[i],"--zoom")==0){
} else if (strcmp(argv[i],"--netsim-lossrate")==0){
i++;
out->netsim_lossrate=atoi(argv[i]);
if(out->netsim_lossrate < 0) {
ms_warning("%d < 0, wrong value for --lost-rate: set to 0", out->netsim_lossrate);
out->netsim_lossrate=0;
}
if(out->netsim_lossrate > 100) {
ms_warning("%d > 100, wrong value for --lost-rate: set to 100", out->netsim_lossrate);
out->netsim_lossrate=100;
}
} else if (strcmp(argv[i],"--zoom")==0){
i++;
if (sscanf(argv[i], "%f,%f,%f", &out->zoom, &out->zoom_cx, &out->zoom_cy) != 3) {
ms_error("Invalid zoom triplet");
......@@ -627,12 +640,19 @@ void setup_media_streams(MediastreamDatas* args) {
printf("Error: video support not compiled.\n");
#endif
}
OrtpNetworkSimulatorParams params={0};
if (args->netsim_bw>0){
OrtpNetworkSimulatorParams params={0};
params.enabled=TRUE;
params.max_bandwidth=args->netsim_bw;
}
if (args->netsim_lossrate>0){
params.enabled=TRUE;
params.loss_rate=args->netsim_lossrate;
}
if (params.enabled){
rtp_session_enable_network_simulation(args->session,&params);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment