plc_context_t *generic_plc_create_context(int sample_rate) { int i; plc_context_t *context = (plc_context_t*) ms_new0(plc_context_t, 1); /* Continuity buffer usage : * Regular: store the last TRANSITION_DELAY ms of signal of each arriving frame, restored at the begining of next frame * PLC mode: store 2*TRANSITION_DELAY ms of PLC signal * - the first TRANSITION_DELAY ms will be used to populate the begining of first frame arrived after PLC, so we can save the end of arrived frame, * - the second TRANSITION_DELAY ms are mixed for smooth transition with the begining of arrived frame */ context->continuity_buffer = ms_malloc0(2*sample_rate*sizeof(int16_t)*TRANSITION_DELAY/1000); /* continuity buffer introduce a TRANSITION_DELAY ms delay */ context->plc_buffer_len = (uint16_t)(sample_rate*sizeof(int16_t)*PLC_BUFFER_LEN); /* length in bytes of the plc_buffer */ context->plc_buffer = ms_malloc0(context->plc_buffer_len); context->hamming_window = ms_malloc0(sample_rate*PLC_BUFFER_LEN*sizeof(float)); context->plc_out_buffer = ms_malloc0(2*context->plc_buffer_len); context->plc_index=0; context->plc_samples_used=0; context->sample_rate = sample_rate; /* initialise the fft contexts, one with sample number being the plc buffer length, * the complex to real is twice that number as buffer is doubled in frequency domain */ context->fft_to_frequency_context = ms_fft_init(sample_rate*PLC_BUFFER_LEN); context->fft_to_time_context = ms_fft_init(2*sample_rate*PLC_BUFFER_LEN); /* initialise hamming window : h(t) = 0.75 - 0.25*cos(2pi*t/T) */ for(i=0; i<sample_rate*PLC_BUFFER_LEN; i++) { context->hamming_window[i] = (float)(0.75 - 0.25*cos( 2*PI*i/(sample_rate*PLC_BUFFER_LEN))); } return context; }
static void dec_init(MSFilter *f){ AMediaFormat *format; AMediaCodec *codec = AMediaCodec_createDecoderByType("video/avc"); DecData *d=ms_new0(DecData,1); d->codec = codec; d->sps=NULL; d->pps=NULL; rfc3984_init(&d->unpacker); d->packet_num=0; d->vsize.width=0; d->vsize.height=0; d->bitstream_size=65536; d->avpf_enabled=FALSE; d->bitstream=ms_malloc0(d->bitstream_size); d->buf_allocator = ms_yuv_buf_allocator_new(); ms_average_fps_init(&d->fps, " H264 decoder: FPS: %f"); format = AMediaFormat_new(); AMediaFormat_setString(format,"mime","video/avc"); //Size mandatory for decoder configuration AMediaFormat_setInt32(format,"width",1920); AMediaFormat_setInt32(format,"height",1080); AMediaCodec_configure(codec, format, NULL, NULL, 0); AMediaCodec_start(codec); AMediaFormat_delete(format); f->data=d; }
static void dec_init(MSFilter *f) { DecData *d = (DecData*)ms_new(DecData,1); JNIEnv *jni_env = NULL; JavaVM *jvm = ms_get_jvm(); (*jvm)->AttachCurrentThread(jvm, &jni_env, NULL); d->h264_construct_id = (*jni_env)->GetMethodID(jni_env, h264_codec_class, "<init>", "(IIIII)V"); d->h264_decode_id = (*jni_env)->GetMethodID(jni_env, h264_codec_class, "decode", "([BI[B)I"); d->h264_close_id = (*jni_env)->GetMethodID(jni_env, h264_codec_class, "close", "()V"); d->input_data = (*jni_env)->NewByteArray(jni_env, VIDEO_DEC_MAX_WIDTH*VIDEO_DEC_MAX_HEIGHT*3/2); d->input_data = (*jni_env)->NewGlobalRef(jni_env, d->input_data); d->output_data = (*jni_env)->NewByteArray(jni_env, VIDEO_DEC_MAX_WIDTH*VIDEO_DEC_MAX_HEIGHT*3/2); d->output_data = (*jni_env)->NewGlobalRef(jni_env, d->output_data); (*jvm)->DetachCurrentThread(jvm); d->yuv_msg = NULL; d->sps = NULL; d->pps = NULL; rfc3984_init(&d->unpacker); d->packet_num = 0; d->bitstream_size = VIDEO_DEC_MAX_WIDTH*VIDEO_DEC_MAX_HEIGHT*3/2; d->bitstream = (uint8_t*)ms_malloc0(d->bitstream_size); d->IsFirstImageDec = FALSE; d->IsRecivedFirstIframe = FALSE; d->IsRecivedSps = FALSE; d->IsRecivedPps = FALSE; f->data = d; }
static void yuv2rgb_prepare(Yuv2RgbCtx *ctx, MSVideoSize src, MSVideoSize dst) { if (ctx->sws!=NULL) yuv2rgb_uninit(ctx); ctx->sws=ms_scaler_create_context(src.width,src.height,MS_YUV420P, dst.width,dst.height, MS_RGB24_REV, MS_SCALER_METHOD_BILINEAR); ctx->dsize=dst; ctx->ssize=src; ctx->rgblen=dst.width*dst.height*3; ctx->rgb=(uint8_t*)ms_malloc0(ctx->rgblen+dst.width); }
static char *flatten_number(const char *number){ char *result=ms_malloc0(strlen(number)+1); char *w=result; const char *r; for(r=number;*r!='\0';++r){ if (*r=='+' || isdigit(*r)){ *w++=*r; } } *w++='\0'; return result; }
MSOpenH264Decoder::MSOpenH264Decoder(MSFilter *f) : mFilter(f), mDecoder(0), mUnpacker(0), mSPS(0), mPPS(0), mYUVMsg(0), mBitstream(0), mBitstreamSize(65536), mLastErrorReportTime(0), mWidth(MS_VIDEO_SIZE_UNKNOWN_W), mHeight(MS_VIDEO_SIZE_UNKNOWN_H), mInitialized(false), mFirstImageDecoded(false) { long ret = WelsCreateDecoder(&mDecoder); if (ret != 0) { ms_error("OpenH264 decoder: Failed to create decoder: %li", ret); } else { mBitstream = static_cast<uint8_t *>(ms_malloc0(mBitstreamSize)); } }
void generic_plc_fftbf(plc_context_t *context, int16_t *input_buffer, int16_t *output_buffer, size_t input_buffer_len) { /* Allocate temporary buffers to perform FFT-> double buffer size in frequency domain -> inverse FFT */ ms_word16_t *time_domain_buffer = ms_malloc0(input_buffer_len*sizeof(ms_word16_t)); ms_word16_t *freq_domain_buffer = ms_malloc0(input_buffer_len*sizeof(ms_word16_t)); ms_word16_t *freq_domain_buffer_double = ms_malloc0(2*input_buffer_len*sizeof(ms_word16_t)); ms_word16_t *time_domain_buffer_double = ms_malloc0(2*input_buffer_len*sizeof(ms_word16_t)); size_t i; /* convert to ms_word16_t the input buffer */ for (i=0; i<input_buffer_len; i++) { time_domain_buffer[i] = (ms_word16_t)((float)input_buffer[i]*context->hamming_window[i]); } /* FFT */ ms_fft(context->fft_to_frequency_context, time_domain_buffer, freq_domain_buffer); /* double the number of sample in frequency domain */ for (i=0; i<input_buffer_len; i++) { freq_domain_buffer_double[2*i] = freq_domain_buffer[i]*ENERGY_ATTENUATION; freq_domain_buffer_double[2*i+1] = 0;//freq_domain_buffer[i]/2 ; } /* inverse FFT, we have twice the number of original samples, discard the first half and use the second as new samples */ ms_ifft(context->fft_to_time_context, freq_domain_buffer_double, time_domain_buffer_double); ms_free(time_domain_buffer); ms_free(freq_domain_buffer); ms_free(freq_domain_buffer_double); /* copy generated signal to the plc_out_buffer */ for (i=0; i<2*input_buffer_len; i++) { output_buffer[i] = (int16_t)(time_domain_buffer_double[i]); } ms_free(time_domain_buffer_double); }
static void dec_init(MSFilter *f){ DecData *d=(DecData*)ms_new(DecData,1); ffmpeg_init(); d->yuv_msg=NULL; d->sps=NULL; d->pps=NULL; d->sws_ctx=NULL; rfc3984_init(&d->unpacker); d->packet_num=0; dec_open(d); d->outbuf.w=0; d->outbuf.h=0; d->bitstream_size=65536; d->bitstream=(uint8_t *)ms_malloc0(d->bitstream_size); f->data=d; }
static MediastreamDatas *init_default_args() { MediastreamDatas *args = (MediastreamDatas *) ms_malloc0(sizeof(MediastreamDatas)); args->payload = 0; args->is_verbose = FALSE; args->playback_card = NULL; args->infile = NULL; args->pt = NULL; args->profile = NULL; args->read = NULL; args->write = NULL; args->decoder = NULL; args->ticker = NULL; return args; }
static void dec_init(MSFilter *f){ DecData *d=(DecData*)ms_new(DecData,1); ffmpeg_init(); d->yuv_msg=NULL; d->sps=NULL; d->pps=NULL; d->sws_ctx=NULL; rfc3984_init(&d->unpacker); d->packet_num=0; dec_open(d); d->outbuf.w=0; d->outbuf.h=0; d->bitstream_size=65536; d->bitstream=ms_malloc0(d->bitstream_size); d->orig = av_frame_alloc(); if (!d->orig) { ms_error("Could not allocate frame"); } f->data=d; }
static void filter_init ( MSFilter *f ) { ISACFIX_MainStruct* isac_mainstruct = NULL; struct _isac_encoder_struct_t *obj = NULL; int instance_size; WebRtc_Word16 ret; f->data = ms_new0(isac_encoder_struct_t, 1); obj = (isac_encoder_struct_t*)f->data; ret = WebRtcIsacfix_AssignSize( &instance_size ); if( ret ) { ms_error("WebRtcIsacfix_AssignSize returned size %d", instance_size); } isac_mainstruct = ms_malloc0(instance_size); ret = WebRtcIsacfix_Assign(&obj->isac, isac_mainstruct); if( ret ) { ms_error("WebRtcIsacfix_Create failed (%d)", ret); } // TODO: AUTO or USER coding mode? ret = WebRtcIsacfix_EncoderInit(obj->isac, CODING_USERDEFINED); if( ret ) { ms_error("WebRtcIsacfix_EncoderInit failed (%d)", WebRtcIsacfix_GetErrorCode(obj->isac)); } obj->ptime = 30; // iSAC allows 30 or 60ms per packet obj->bitrate = ISAC_BITRATE_MAX; ret = WebRtcIsacfix_Control(obj->isac, obj->bitrate, obj->ptime); if( ret ) { ms_error("WebRtcIsacfix_Control failed: %d", WebRtcIsacfix_GetErrorCode(obj->isac)); } obj->bufferizer = ms_bufferizer_new(); obj->ts = 0; }
static void fetch_config(SpeexECState *s){ SpeexEchoStateBlob *blob=NULL; char *txt; size_t txt_len; if (s->ecstate==NULL) return; if (speex_echo_ctl(s->ecstate, SPEEX_ECHO_GET_BLOB, &blob)!=0){ ms_error("Could not retrieve speex echo blob !"); return; } txt_len=(speex_echo_state_blob_get_size(blob)*4)+1; txt=ms_malloc0(txt_len); if (b64_encode(speex_echo_state_blob_get_data(blob),speex_echo_state_blob_get_size(blob), txt,txt_len)==0){ ms_error("Base64 encoding failed."); ms_free(txt); return; } speex_echo_state_blob_free(blob); if (s->state_str) ms_free(s->state_str); s->state_str=txt; }
int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){ int err; //char dns_answer[DNS_ANSWER_MAX_SIZE]; char *begin,*end; char *host_result, *command; int i; bool_t forkok; /* ns_msg handle; int count; memset(&handle,0,sizeof(handle)); *res=NULL; ms_message("Resolving %s...",enum_domain); err=res_search(enum_domain,ns_c_in,ns_t_naptr,dns_answer,DNS_ANSWER_MAX_SIZE); if (err<0){ ms_warning("Error resolving enum:",herror(h_errno)); return -1; } ns_initparse(dns_answer,DNS_ANSWER_MAX_SIZE,&handle); count=ns_msg_count(handle,ns_s_an); for(i=0;i<count;i++){ ns_rr rr; memset(&rr,0,sizeof(rr)); ns_parserr(&handle,ns_s_an,i,&rr); ms_message("data=%s",ns_rr_rdata(rr)); } */ command=ms_strdup_printf("host -t naptr %s",enum_domain); forkok=lp_spawn_command_line_sync(command,&host_result,&err); ms_free(command); if (forkok){ if (err!=0){ ms_warning("Host exited with %i error status.",err); return -1; } }else{ ms_warning("Could not spawn the \'host\' command."); return -1; } ms_message("Answer received from dns (err=%i): %s",err,host_result); begin=strstr(host_result,"sip:"); if (begin==0) { ms_warning("No sip address found in dns naptr answer."); return -1; } *res=ms_malloc0(sizeof(enum_lookup_res_t)); err=0; for(i=0;i<MAX_ENUM_LOOKUP_RESULTS;i++){ end=strstr(begin,"!"); if (end==NULL) goto parse_error; end[0]='\0'; (*res)->sip_address[i]=ms_strdup(begin); err++; begin=strstr(end+1,"sip:"); if (begin==NULL) break; } ms_free(host_result); return err; parse_error: ms_free(*res); ms_free(host_result); *res=NULL; ms_warning("Parse error in enum_lookup()."); return -1; }
int ms_factory_load_plugins(MSFactory *factory, const char *dir){ int num=0; #if defined(_WIN32) && !defined(_WIN32_WCE) WIN32_FIND_DATA FileData; HANDLE hSearch; char szDirPath[1024]; #ifdef UNICODE wchar_t wszDirPath[1024]; #endif char szPluginFile[1024]; BOOL fFinished = FALSE; const char *tmp = NULL; BOOL debug = FALSE; #ifndef MS2_WINDOWS_UNIVERSAL tmp = getenv("DEBUG"); #endif debug = (tmp != NULL && atoi(tmp) == 1); snprintf(szDirPath, sizeof(szDirPath), "%s", dir); // Start searching for .dll files in the current directory. #ifdef MS2_WINDOWS_DESKTOP snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir); #else snprintf(szDirPath, sizeof(szDirPath), "%s\\libms*.dll", dir); #endif #ifdef UNICODE mbstowcs(wszDirPath, szDirPath, sizeof(wszDirPath)); hSearch = FindFirstFileExW(wszDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); #else hSearch = FindFirstFileExA(szDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); #endif if (hSearch == INVALID_HANDLE_VALUE) { ms_message("no plugin (*.dll) found in [%s] [%d].", szDirPath, (int)GetLastError()); return 0; } snprintf(szDirPath, sizeof(szDirPath), "%s", dir); while (!fFinished) { /* load library */ #ifdef MS2_WINDOWS_DESKTOP UINT em=0; #endif HINSTANCE os_handle; #ifdef UNICODE wchar_t wszPluginFile[2048]; char filename[512]; wcstombs(filename, FileData.cFileName, sizeof(filename)); snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, filename); mbstowcs(wszPluginFile, szPluginFile, sizeof(wszPluginFile)); #else snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName); #endif #ifdef MS2_WINDOWS_DESKTOP if (!debug) em = SetErrorMode (SEM_FAILCRITICALERRORS); #ifdef UNICODE os_handle = LoadLibraryExW(wszPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); #else os_handle = LoadLibraryExA(szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); #endif if (os_handle==NULL) { ms_message("Fail to load plugin %s with altered search path: error %i",szPluginFile,(int)GetLastError()); #ifdef UNICODE os_handle = LoadLibraryExW(wszPluginFile, NULL, 0); #else os_handle = LoadLibraryExA(szPluginFile, NULL, 0); #endif } if (!debug) SetErrorMode (em); #else os_handle = LoadPackagedLibrary(wszPluginFile, 0); #endif if (os_handle==NULL) ms_error("Fail to load plugin %s: error %i", szPluginFile, (int)GetLastError()); else{ init_func_t initroutine; char szPluginName[256]; char szMethodName[256]; char *minus; #ifdef UNICODE snprintf(szPluginName, sizeof(szPluginName), "%s", filename); #else snprintf(szPluginName, sizeof(szPluginName), "%s", FileData.cFileName); #endif /*on mingw, dll names might be libsomething-3.dll. We must skip the -X.dll stuff*/ minus=strchr(szPluginName,'-'); if (minus) *minus='\0'; else szPluginName[strlen(szPluginName)-4]='\0'; /*remove .dll*/ snprintf(szMethodName, sizeof(szMethodName), "%s_init", szPluginName); initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName); if (initroutine!=NULL){ initroutine(factory); ms_message("Plugin loaded (%s)", szPluginFile); // Add this new loaded plugin to the list (useful for FreeLibrary at the end) factory->ms_plugins_loaded_list=ms_list_append(factory->ms_plugins_loaded_list,os_handle); num++; }else{ ms_warning("Could not locate init routine of plugin %s. Should be %s", szPluginFile, szMethodName); } } if (!FindNextFile(hSearch, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES){ fFinished = TRUE; } else { ms_error("couldn't find next plugin dll."); fFinished = TRUE; } } } /* Close the search handle. */ FindClose(hSearch); #elif defined(HAVE_DLOPEN) char plugin_name[64]; DIR *ds; MSList *loaded_plugins = NULL; struct dirent *de; char *ext; char *fullpath; ds=opendir(dir); if (ds==NULL){ ms_message("Cannot open directory %s: %s",dir,strerror(errno)); return -1; } while( (de=readdir(ds))!=NULL){ if ( #ifndef __QNX__ (de->d_type==DT_REG || de->d_type==DT_UNKNOWN || de->d_type==DT_LNK) && #endif (ext=strstr(de->d_name,PLUGINS_EXT))!=NULL) { void *handle; snprintf(plugin_name, MIN(sizeof(plugin_name), ext - de->d_name + 1), "%s", de->d_name); if (ms_list_find_custom(loaded_plugins, (MSCompareFunc)strcmp, plugin_name) != NULL) continue; loaded_plugins = ms_list_append(loaded_plugins, ms_strdup(plugin_name)); fullpath=ms_strdup_printf("%s/%s",dir,de->d_name); ms_message("Loading plugin %s...",fullpath); if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ ms_warning("Fail to load plugin %s : %s",fullpath,dlerror()); }else { char *initroutine_name=ms_malloc0(strlen(de->d_name)+10); char *p; void *initroutine=NULL; strcpy(initroutine_name,de->d_name); p=strstr(initroutine_name,PLUGINS_EXT); if (p!=NULL){ strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } #ifdef __APPLE__ if (initroutine==NULL){ /* on macosx: library name are libxxxx.1.2.3.dylib */ /* -> MUST remove the .1.2.3 */ p=strstr(initroutine_name,"."); if (p!=NULL) { strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } } #endif if (initroutine!=NULL){ init_func_t func=(init_func_t)initroutine; func(factory); ms_message("Plugin loaded (%s)", fullpath); num++; }else{ ms_warning("Could not locate init routine of plugin %s",de->d_name); } ms_free(initroutine_name); } ms_free(fullpath); } } ms_list_for_each(loaded_plugins, ms_free); ms_list_free(loaded_plugins); closedir(ds); #else ms_warning("no loadable plugin support: plugins cannot be loaded."); num=-1; #endif return num; }
/** * @briefThis function is called by ZRTP engine as soon as SRTP secrets are ready to be used * Depending on which role we assume in the ZRTP protocol (Initiator or Responder, randomly selected) * both secrets may not be available at the same time, the part argument is either * ZRTP_SRTP_SECRETS_FOR_SENDER or ZRTP_SRTP_SECRETS_FOR_RECEIVER. * Secrets are used to set up SRTP sessions * * @param[in] clientData Pointer to our ZrtpContext structure used to retrieve stream sessions structure needed to setup SRTP sessions * @param[in] secrets The SRTP keys and algorithm setup * @param[in] part for receiver or for sender in order to determine which SRTP stream the secret apply to * @return 0 on success */ static int32_t ms_zrtp_srtpSecretsAvailable(void* clientData, bzrtpSrtpSecrets_t* secrets, uint8_t part) { MSZrtpContext *userData = (MSZrtpContext *)clientData; // Get authentication and cipher algorithms in srtp format if ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS32) && ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS80))) { ms_fatal("unsupported authentication algorithm by srtp"); } if ((secrets->cipherAlgo != ZRTP_CIPHER_AES1) && (secrets->cipherAlgo != ZRTP_CIPHER_AES3)) { ms_fatal("unsupported cipher algorithm by srtp"); } ms_message("ZRTP secrets are ready for %s; auth tag algo is %s and cipher algo is %s", (part==ZRTP_SRTP_SECRETS_FOR_SENDER)?"sender":"receiver", (secrets->authTagAlgo==ZRTP_AUTHTAG_HS32)?"HS32":"HS80", (secrets->cipherAlgo==ZRTP_CIPHER_AES3)?"AES256":"AES128"); if (part==ZRTP_SRTP_SECRETS_FOR_RECEIVER) { uint8_t *key = (uint8_t *)ms_malloc0((secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength+16)*sizeof(uint8_t)); memcpy(key, secrets->peerSrtpKey, secrets->peerSrtpKeyLength); memcpy(key + secrets->peerSrtpKeyLength, secrets->peerSrtpSalt, secrets->peerSrtpSaltLength); if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_256_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_128_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_256_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else{ ms_fatal("unsupported auth tag"); } ms_free(key); } if (part==ZRTP_SRTP_SECRETS_FOR_SENDER) { uint8_t *key = (uint8_t *)ms_malloc0((secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength+16)*sizeof(uint8_t)); memcpy(key, secrets->selfSrtpKey, secrets->selfSrtpKeyLength); memcpy(key + secrets->selfSrtpKeyLength, secrets->selfSrtpSalt, secrets->selfSrtpSaltLength); if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_256_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_128_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_256_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else{ ms_fatal("unsupported auth tag"); } ms_free(key); } return 0; }
int ms_discover_mtu(const char *host){ int sock; int err,mtu=0,new_mtu; socklen_t optlen; char port[10]; struct addrinfo hints,*ai=NULL; int family = PF_INET; int rand_port; int retry=0; struct timeval tv; /* Try to get the address family of the host (PF_INET or PF_INET6). */ memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; err = getaddrinfo(host, NULL, &hints, &ai); if (err == 0) family = ai->ai_family; memset(&hints,0,sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; gettimeofday(&tv,NULL); srandom(tv.tv_usec); rand_port=random() & 0xFFFF; if (rand_port<1000) rand_port+=1000; snprintf(port,sizeof(port),"%i",rand_port); err=getaddrinfo(host,port,&hints,&ai); if (err!=0){ ms_error("getaddrinfo(): %s\n",gai_strerror(err)); return -1; } sock=socket(family,SOCK_DGRAM,0); if(sock < 0) { ms_error("socket(): %s",strerror(errno)); return sock; } mtu = (family == PF_INET6) ? IPV6_PMTUDISC_DO: IP_PMTUDISC_DO; optlen=sizeof(mtu); err=setsockopt(sock,(family == PF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP,(family == PF_INET6) ? IPV6_MTU_DISCOVER : IP_MTU_DISCOVER,&mtu,optlen); if (err!=0){ ms_error("setsockopt(): %s",strerror(errno)); err = close(sock); if (err!=0) ms_error("close(): %s", strerror(errno)); return -1; } err=connect(sock,ai->ai_addr,ai->ai_addrlen); freeaddrinfo(ai); if (err!=0){ ms_error("connect(): %s",strerror(errno)); err = close(sock); if (err !=0) ms_error("close(): %s", strerror(errno)); return -1; } mtu=1500; do{ int send_returned; int datasize = mtu - (UDP_HEADER_SIZE + ((family == PF_INET6) ? IPV6_HEADER_SIZE : IPV4_HEADER_SIZE)); /*minus IP+UDP overhead*/ char *buf=ms_malloc0(datasize); send_returned = send(sock,buf,datasize,0); if (send_returned==-1){ /*ignore*/ } ms_free(buf); usleep(500000);/*wait for an icmp message come back */ err=getsockopt(sock,(family == PF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP,(family == PF_INET6) ? IPV6_MTU : IP_MTU,&new_mtu,&optlen); if (err!=0){ ms_error("getsockopt(): %s",strerror(errno)); err = close(sock); if (err!=0) ms_error("close(): %s", strerror(errno)); return -1; }else{ ms_message("Partial MTU discovered : %i",new_mtu); if (new_mtu==mtu) break; else mtu=new_mtu; } retry++; }while(retry<10); ms_message("mtu to %s is %i",host,mtu); err = close(sock); if (err!=0) ms_error("close() %s", strerror(errno)); return mtu; }
int ms_load_plugins(const char *dir){ int num=0; #if defined(WIN32) && !defined(_WIN32_WCE) WIN32_FIND_DATA FileData; HANDLE hSearch; char szDirPath[1024]; char szPluginFile[1024]; BOOL fFinished = FALSE; const char *tmp=getenv("DEBUG"); BOOL debug=(tmp!=NULL && atoi(tmp)==1); snprintf(szDirPath, sizeof(szDirPath), "%s", dir); // Start searching for .dll files in the current directory. snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir); hSearch = FindFirstFile(szDirPath, &FileData); if (hSearch == INVALID_HANDLE_VALUE) { ms_message("no plugin (*.dll) found in %s.", szDirPath); return 0; } snprintf(szDirPath, sizeof(szDirPath), "%s", dir); while (!fFinished) { /* load library */ HINSTANCE os_handle; UINT em; if (!debug) em = SetErrorMode (SEM_FAILCRITICALERRORS); snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName); os_handle = LoadLibraryEx (szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (os_handle==NULL) { ms_message("Fail to load plugin %s with altered search path: error %i",szPluginFile,GetLastError()); os_handle = LoadLibraryEx (szPluginFile, NULL, 0); } if (!debug) SetErrorMode (em); if (os_handle==NULL) ms_error("Fail to load plugin %s", szPluginFile); else{ init_func_t initroutine; char szPluginName[256]; char szMethodName[256]; char *minus; snprintf(szPluginName, 256, "%s", FileData.cFileName); /*on mingw, dll names might be libsomething-3.dll. We must skip the -X.dll stuff*/ minus=strchr(szPluginName,'-'); if (minus) *minus='\0'; else szPluginName[strlen(szPluginName)-4]='\0'; /*remove .dll*/ snprintf(szMethodName, 256, "%s_init", szPluginName); initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName); if (initroutine!=NULL){ initroutine(); ms_message("Plugin loaded (%s)", szPluginFile); num++; }else{ ms_warning("Could not locate init routine of plugin %s. Should be %s", szPluginFile, szMethodName); } } if (!FindNextFile(hSearch, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES){ fFinished = TRUE; } else { ms_error("couldn't find next plugin dll."); fFinished = TRUE; } } } /* Close the search handle. */ FindClose(hSearch); #elif HAVE_DLOPEN DIR *ds; struct dirent *de; char *fullpath; ds=opendir(dir); if (ds==NULL){ ms_message("Cannot open directory %s: %s",dir,strerror(errno)); return -1; } while( (de=readdir(ds))!=NULL){ if ((de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL) || (de->d_type==DT_UNKNOWN && strstr(de->d_name,PLUGINS_EXT)==de->d_name+strlen(de->d_name)-strlen(PLUGINS_EXT))) { void *handle; fullpath=ms_strdup_printf("%s/%s",dir,de->d_name); ms_message("Loading plugin %s...",fullpath); if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ ms_warning("Fail to load plugin %s : %s",fullpath,dlerror()); }else { char *initroutine_name=ms_malloc0(strlen(de->d_name)+10); char *p; void *initroutine=NULL; strcpy(initroutine_name,de->d_name); p=strstr(initroutine_name,PLUGINS_EXT); if (p!=NULL){ strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } #ifdef __APPLE__ if (initroutine==NULL){ /* on macosx: library name are libxxxx.1.2.3.dylib */ /* -> MUST remove the .1.2.3 */ p=strstr(initroutine_name,"."); if (p!=NULL) { strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } } #endif if (initroutine!=NULL){ init_func_t func=(init_func_t)initroutine; func(); ms_message("Plugin loaded (%s)", fullpath); num++; }else{ ms_warning("Could not locate init routine of plugin %s",de->d_name); } ms_free(initroutine_name); } ms_free(fullpath); } } closedir(ds); #else ms_warning("no loadable plugin support: plugins cannot be loaded."); num=-1; #endif return num; }
/** * Check if the incoming message is a DTLS packet. * If it is, store it in the context incoming buffer and call the polarssl function wich will process it. * This function also manages the client retransmission timer * * @param[in] msg the incoming message * @param[in/out] ctx the context containing the incoming buffer to store the DTLS packet * @param[out] ret the value returned by the polarssl function processing the packet(ssl_handshake) * @param[in] is_rtp TRUE if we are dealing with a RTP channel packet, FALSE for RTCP channel * @return TRUE if packet is a DTLS one, false otherwise */ static bool_t ms_dtls_srtp_process_dtls_packet(mblk_t *msg, MSDtlsSrtpContext *ctx, int *ret, bool_t is_rtp) { size_t msgLength = msgdsize(msg); uint64_t *time_reference = (is_rtp == TRUE)?&(ctx->rtp_time_reference):&(ctx->rtcp_time_reference); ssl_context *ssl = (is_rtp == TRUE)?&(ctx->rtp_dtls_context->ssl):&(ctx->rtcp_dtls_context->ssl); ms_mutex_t *mutex = (is_rtp == TRUE)?&ctx->rtp_dtls_context->ssl_context_mutex:&ctx->rtcp_dtls_context->ssl_context_mutex; // check if incoming message length is compatible with potential DTLS message if (msgLength<RTP_FIXED_HEADER_SIZE) { return FALSE; } /* check if it is a DTLS packet (first byte B as 19 < B < 64) rfc5764 section 5.1.2 */ if ((*(msg->b_rptr)>19) && (*(msg->b_rptr)<64)) { DtlsRawPacket *incoming_dtls_packet; RtpSession *rtp_session = ctx->stream_sessions->rtp_session; OrtpStream *ortp_stream = is_rtp?&rtp_session->rtp.gs:&rtp_session->rtcp.gs; incoming_dtls_packet = (DtlsRawPacket *)ms_malloc0(sizeof(DtlsRawPacket)); //DtlsRawPacket *incoming_dtls_packet = (DtlsRawPacket *)ms_malloc0(sizeof(DtlsRawPacket)); incoming_dtls_packet->next=NULL; incoming_dtls_packet->data=(unsigned char *)ms_malloc(msgLength); incoming_dtls_packet->length=msgLength; memcpy(incoming_dtls_packet->data, msg->b_rptr, msgLength); /*required by webrtc in server case when ice is not completed yet*/ if (!rtp_session->use_connect){ struct sockaddr *addr = NULL; socklen_t addrlen; addr = (struct sockaddr *)&msg->net_addr; addrlen = msg->net_addrlen; if (ortp_stream->socket>0 && rtp_session->symmetric_rtp){ /* store the sender rtp address to do symmetric DTLS */ memcpy(&ortp_stream->rem_addr,addr,addrlen); ortp_stream->rem_addrlen=addrlen; } } /* store the packet in the incoming buffer */ if (is_rtp == TRUE) { if (ctx->rtp_incoming_buffer==NULL) { /* buffer is empty */ ctx->rtp_incoming_buffer = incoming_dtls_packet; } else { /* queue it at the end of current buffer */ DtlsRawPacket *last_packet = ctx->rtp_incoming_buffer; while (last_packet->next != NULL) last_packet = last_packet->next; last_packet->next = incoming_dtls_packet; } } else { if (ctx->rtcp_incoming_buffer==NULL) { /* buffer is empty */ ctx->rtcp_incoming_buffer = incoming_dtls_packet; } else { /* queue it at the end of current buffer */ DtlsRawPacket *last_packet = ctx->rtcp_incoming_buffer; while (last_packet->next != NULL) last_packet = last_packet->next; last_packet->next = incoming_dtls_packet; } } /* role is unset but we receive a packet: we are caller and shall initialise as server and then process the incoming packet */ if (ctx->role == MSDtlsSrtpRoleUnset) { ms_dtls_srtp_set_role(ctx, MSDtlsSrtpRoleIsServer); /* this call will update role and complete server setup */ } ms_mutex_lock(mutex); /* process the packet and store result */ *ret = ssl_handshake(ssl); /* when we are server, we may issue a hello verify, so reset session, keep cookies(transport id) and expect an other Hello from client */ if (*ret==POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED) { ssl_session_reset(ssl); ssl_set_client_transport_id(ssl, (const unsigned char *)(&(ctx->stream_sessions->rtp_session->snd.ssrc)), 4); } /* if we are client, manage the retransmission timer */ if (ctx->role == MSDtlsSrtpRoleIsClient) { *time_reference = get_timeval_in_millis(); } ms_mutex_unlock(mutex); return TRUE; } return FALSE; }
static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvider* obj, const LinphoneDictionary* dict) { char* attributes_list, *saveptr, *attr; unsigned int attr_count = 0, attr_idx = 0, i; if( !linphone_ldap_contact_provider_valid_config(dict) ) return; // free any pre-existing attributes values linphone_ldap_contact_provider_conf_destroy(obj); if( obj->config ) linphone_dictionary_unref(obj->config); // clone new config into the dictionary obj->config = linphone_dictionary_ref(linphone_dictionary_clone(dict)); #if 0 // until sasl auth is set up, force anonymous auth. linphone_dictionary_set_string(obj->config, "auth_method", "ANONYMOUS"); #endif obj->use_tls = linphone_dictionary_get_int(obj->config, "use_tls", 0); obj->timeout = linphone_dictionary_get_int(obj->config, "timeout", 10); obj->deref_aliases = linphone_dictionary_get_int(obj->config, "deref_aliases", 0); obj->max_results = linphone_dictionary_get_int(obj->config, "max_results", 50); obj->auth_method = linphone_dictionary_get_string(obj->config, "auth_method", "ANONYMOUS"); obj->username = linphone_dictionary_get_string(obj->config, "username", ""); obj->password = linphone_dictionary_get_string(obj->config, "password", ""); obj->bind_dn = linphone_dictionary_get_string(obj->config, "bind_dn", ""); obj->base_object = linphone_dictionary_get_string(obj->config, "base_object", "dc=example,dc=com"); obj->server = linphone_dictionary_get_string(obj->config, "server", "ldap://localhost"); obj->filter = linphone_dictionary_get_string(obj->config, "filter", "uid=*%s*"); obj->name_attr = linphone_dictionary_get_string(obj->config, "name_attribute", "givenName"); obj->sip_attr = linphone_dictionary_get_string(obj->config, "sip_attribute", "mobile"); obj->sasl_authname = linphone_dictionary_get_string(obj->config, "sasl_authname", ""); obj->sasl_realm = linphone_dictionary_get_string(obj->config, "sasl_realm", ""); /* * parse the attributes list */ attributes_list = ms_strdup( linphone_dictionary_get_string(obj->config, "attributes", "telephoneNumber,givenName,sn,mobile,homePhone") ); // count attributes: for( i=0; attributes_list[i]; i++) { if( attributes_list[i] == ',') attr_count++; } // 1 more for the first attr without ',', the other for the null-finished list obj->attributes = ms_malloc0((attr_count+2) * sizeof(char*)); attr = strtok_r( attributes_list, ",", &saveptr ); while( attr != NULL ){ obj->attributes[attr_idx] = ms_strdup(attr); attr_idx++; attr = strtok_r(NULL, ",", &saveptr); } if( attr_idx != attr_count+1) ms_error("Invalid attribute number!!! %d expected, got %d", attr_count+1, attr_idx); ms_free(attributes_list); }
static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){ #ifndef NO_FFMPEG AVCodecContext av_context; int got_picture=0; AVFrame orig; mblk_t *ret; struct SwsContext *sws_ctx; AVPacket pkt; MSPicture dest; AVCodec *codec=avcodec_find_decoder(CODEC_ID_MJPEG); if (codec==NULL){ ms_error("Could not find MJPEG decoder in ffmpeg."); return NULL; } avcodec_get_context_defaults(&av_context); if (avcodec_open(&av_context,codec)<0){ ms_error("jpeg2yuv: avcodec_open failed"); return NULL; } av_init_packet(&pkt); pkt.data=jpgbuf; pkt.size=bufsize; if (avcodec_decode_video2(&av_context,&orig,&got_picture,&pkt) < 0) { ms_error("jpeg2yuv: avcodec_decode_video failed"); avcodec_close(&av_context); return NULL; } ret=ms_yuv_buf_alloc(&dest, reqsize->width,reqsize->height); /* not using SWS_FAST_BILINEAR because it doesn't play well with * av_context.pix_fmt set to PIX_FMT_YUVJ420P by jpeg decoder */ sws_ctx=sws_getContext(av_context.width,av_context.height,av_context.pix_fmt, reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_BILINEAR, NULL, NULL, NULL); if (sws_ctx==NULL) { ms_error("jpeg2yuv: ms_sws_getContext() failed."); avcodec_close(&av_context); freemsg(ret); return NULL; } #if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0) if (sws_scale(sws_ctx,(const uint8_t* const *)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){ #else if (sws_scale(sws_ctx,(uint8_t**)orig.data,orig.linesize,0,av_context.height,dest.planes,dest.strides)<0){ #endif ms_error("jpeg2yuv: ms_sws_scale() failed."); sws_freeContext(sws_ctx); avcodec_close(&av_context); freemsg(ret); return NULL; } sws_freeContext(sws_ctx); avcodec_close(&av_context); return ret; #elif TARGET_OS_IPHONE MSPicture dest; CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, jpgbuf, bufsize, NULL); // use the data provider to get a CGImage; release the data provider CGImageRef image = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, FALSE, kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); reqsize->width = CGImageGetWidth(image); reqsize->height = CGImageGetHeight(image); uint8_t* tmp = (uint8_t*) malloc(reqsize->width * reqsize->height * 4); mblk_t* ret=ms_yuv_buf_alloc(&dest, reqsize->width, reqsize->height); CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef imageContext = CGBitmapContextCreate(tmp, reqsize->width, reqsize->height, 8, reqsize->width*4, colourSpace, kCGImageAlphaNoneSkipLast); CGColorSpaceRelease(colourSpace); // draw the image to the context, release it CGContextDrawImage(imageContext, CGRectMake(0, 0, reqsize->width, reqsize->height), image); CGImageRelease(image); /* convert tmp/RGB -> ret/YUV */ for(int y=0; y<reqsize->height; y++) { for(int x=0; x<reqsize->width; x++) { uint8_t r = tmp[y * reqsize->width * 4 + x * 4 + 0]; uint8_t g = tmp[y * reqsize->width * 4 + x * 4 + 1]; uint8_t b = tmp[y * reqsize->width * 4 + x * 4 + 2]; // Y *dest.planes[0]++ = (uint8_t)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16); // U/V subsampling if ((y % 2==0) && (x%2==0)) { uint32_t r32=0, g32=0, b32=0; for(int i=0; i<2; i++) { for(int j=0; j<2; j++) { r32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 0]; g32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 1]; b32 += tmp[(y+i) * reqsize->width * 4 + (x+j) * 4 + 2]; } } r32 = (uint32_t)(r32 * 0.25f); g32 = (uint32_t)(g32 * 0.25f); b32 = (uint32_t) (b32 * 0.25f); // U *dest.planes[1]++ = (uint8_t)(-(0.148 * r32) - (0.291 * g32) + (0.439 * b32) + 128); // V *dest.planes[2]++ = (uint8_t)((0.439 * r32) - (0.368 * g32) - (0.071 * b32) + 128); } } } free(tmp); return ret; #else return NULL; #endif } mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){ #if defined(WIN32) mblk_t *m=NULL; DWORD st_sizel; DWORD st_sizeh; uint8_t *jpgbuf; DWORD err; HANDLE fd; #ifdef UNICODE WCHAR wUnicode[1024]; MultiByteToWideChar(CP_UTF8, 0, jpgpath, -1, wUnicode, 1024); fd = CreateFile(wUnicode, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); #else fd = CreateFile(jpgpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); #endif if (fd==INVALID_HANDLE_VALUE){ ms_error("Failed to open %s",jpgpath); return NULL; } st_sizel=0; st_sizeh=0; st_sizel = GetFileSize(fd, &st_sizeh); if (st_sizeh>0 || st_sizel<=0) { CloseHandle(fd); ms_error("Can't load file %s",jpgpath); return NULL; } jpgbuf=(uint8_t*)ms_malloc0(st_sizel); if (jpgbuf==NULL) { CloseHandle(fd); ms_error("Cannot allocate buffer for %s",jpgpath); return NULL; } err=0; ReadFile(fd, jpgbuf, st_sizel, &err, NULL) ; if (err!=st_sizel){ ms_error("Could not read as much as wanted !"); } m=jpeg2yuv(jpgbuf,st_sizel,reqsize); ms_free(jpgbuf); if (m==NULL) { CloseHandle(fd); ms_error("Cannot load image from buffer for %s",jpgpath); return NULL; } CloseHandle(fd); return m; #else mblk_t *m=NULL; struct stat statbuf; uint8_t *jpgbuf; int err; int fd=open(jpgpath,O_RDONLY); if (fd!=-1){ fstat(fd,&statbuf); if (statbuf.st_size<=0) { close(fd); ms_error("Cannot load %s",jpgpath); return NULL; } jpgbuf=(uint8_t*)ms_malloc0(statbuf.st_size + FF_INPUT_BUFFER_PADDING_SIZE); if (jpgbuf==NULL) { close(fd); ms_error("Cannot allocate buffer for %s",jpgpath); return NULL; } err=read(fd,jpgbuf,statbuf.st_size); if (err!=statbuf.st_size){ ms_error("Could not read as much as wanted: %i<>%li !",err,(long)statbuf.st_size); } m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize); ms_free(jpgbuf); if (m==NULL) { close(fd); ms_error("Cannot load image from buffer for %s",jpgpath); return NULL; } }else{ ms_error("Cannot load %s",jpgpath); return NULL; } close(fd); return m; #endif }
static int ms_dtls_srtp_rtcp_process_on_receive(struct _RtpTransportModifier *t, mblk_t *msg) { MSDtlsSrtpContext *ctx = (MSDtlsSrtpContext *)t->data; int ret; size_t msgLength = msgdsize(msg); // check incoming message length if (msgLength<RTP_FIXED_HEADER_SIZE) { return msgLength; } /* check if we have an on-going handshake */ if (ctx->rtp_channel_status == DTLS_STATUS_CONTEXT_NOT_READY) { return msgLength; } /* check if it is a DTLS packet and process it */ if (ms_dtls_srtp_process_dtls_packet(msg, ctx, &ret, FALSE) == TRUE){ if ((ret==0) && (ctx->rtcp_channel_status == DTLS_STATUS_CONTEXT_READY)) { /* rtcp handshake is over, give the keys to srtp : 128 bits client write - 128 bits server write - 112 bits client salt - 112 server salt */ uint8_t *key = (uint8_t *)ms_malloc0(256); MSCryptoSuite agreed_srtp_protection_profile = MS_CRYPTO_SUITE_INVALID; ctx->rtcp_channel_status = DTLS_STATUS_HANDSHAKE_OVER; /* check the srtp profile get selected during handshake */ agreed_srtp_protection_profile = ms_polarssl_dtls_srtp_protection_profile_to_ms_crypto_suite(ssl_get_dtls_srtp_protection_profile(&(ctx->rtcp_dtls_context->ssl))); if ( agreed_srtp_protection_profile == MS_CRYPTO_SUITE_INVALID) { ms_error("DTLS RTCP Handshake successful but unable to agree on srtp_profile to use"); } else { if (ms_dtls_srtp_check_certificate_fingerprint(ssl_get_peer_cert(&(ctx->rtcp_dtls_context->ssl)), (const char *)(ctx->peer_fingerprint)) == 1) { ms_message("DTLS RTCP Handshake successful and fingerprints match, srtp protection profile %d", ctx->rtcp_dtls_context->ssl.chosen_dtls_srtp_profile); ctx->rtcp_time_reference = 0; /* unarm the timer */ if (ctx->role == MSDtlsSrtpRoleIsServer) { /* reception(client write) key and salt +16bits padding */ memcpy(key, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys, DTLS_SRTP_KEY_LEN); memcpy(key + DTLS_SRTP_KEY_LEN, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+2*DTLS_SRTP_KEY_LEN, DTLS_SRTP_SALT_LEN); ms_media_stream_sessions_set_srtp_recv_key(ctx->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, MSSRTP_RTCP_STREAM); /* emission(server write) key and salt +16bits padding */ memcpy(key, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+DTLS_SRTP_KEY_LEN, DTLS_SRTP_KEY_LEN); memcpy(key + DTLS_SRTP_KEY_LEN, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+2*DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, DTLS_SRTP_SALT_LEN); ms_media_stream_sessions_set_srtp_send_key(ctx->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, MSSRTP_RTCP_STREAM); } else if (ctx->role == MSDtlsSrtpRoleIsClient){ /* this enpoint act as DTLS client */ /* emission(client write) key and salt +16bits padding */ memcpy(key, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys, DTLS_SRTP_KEY_LEN); memcpy(key + DTLS_SRTP_KEY_LEN, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+2*DTLS_SRTP_KEY_LEN, DTLS_SRTP_SALT_LEN); ms_media_stream_sessions_set_srtp_send_key(ctx->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, MSSRTP_RTCP_STREAM); /* reception(server write) key and salt +16bits padding */ memcpy(key, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+DTLS_SRTP_KEY_LEN, DTLS_SRTP_KEY_LEN); memcpy(key + DTLS_SRTP_KEY_LEN, ctx->rtcp_dtls_context->ssl.dtls_srtp_keys+2*DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, DTLS_SRTP_SALT_LEN); ms_media_stream_sessions_set_srtp_recv_key(ctx->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, DTLS_SRTP_KEY_LEN+DTLS_SRTP_SALT_LEN, MSSRTP_RTCP_STREAM); } ms_free(key); ms_dtls_srtp_check_channels_status(ctx); } } ret = ssl_close_notify( &(ctx->rtcp_dtls_context->ssl) ); } return 0; } return msgdsize(msg); }
static void jpg_process(MSFilter *f){ JpegWriter *s=(JpegWriter*)f->data; ms_filter_lock(f); if (s->file!=NULL && s->codec!=NULL){ MSPicture yuvbuf, yuvjpeg; mblk_t *m=ms_queue_peek_last(f->inputs[0]); if (ms_yuv_buf_init_from_mblk(&yuvbuf,m)==0){ int error,got_pict; int comp_buf_sz=msgdsize(m); uint8_t *comp_buf=(uint8_t*)ms_malloc0(comp_buf_sz); mblk_t *jpegm; struct SwsContext *sws_ctx; struct AVPacket packet; AVCodecContext *avctx=avcodec_alloc_context3(s->codec); memset(&packet, 0, sizeof(packet)); avctx->width=yuvbuf.w; avctx->height=yuvbuf.h; avctx->time_base.num = 1; avctx->time_base.den =1; avctx->pix_fmt=AV_PIX_FMT_YUVJ420P; error=avcodec_open2(avctx,s->codec,NULL); if (error!=0) { ms_error("avcodec_open() failed: %i",error); cleanup(s,NULL, FALSE); av_free(avctx); goto end; } sws_ctx=sws_getContext(avctx->width,avctx->height,AV_PIX_FMT_YUV420P, avctx->width,avctx->height,avctx->pix_fmt,SWS_FAST_BILINEAR,NULL, NULL, NULL); if (sws_ctx==NULL) { ms_error(" sws_getContext() failed."); cleanup(s,avctx, FALSE); goto end; } jpegm=ms_yuv_buf_alloc (&yuvjpeg,avctx->width, avctx->height); #if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0) if (sws_scale(sws_ctx,(const uint8_t *const*)yuvbuf.planes,yuvbuf.strides,0,avctx->height,yuvjpeg.planes,yuvjpeg.strides)<0){ #else if (sws_scale(sws_ctx,(uint8_t **)yuvbuf.planes,yuvbuf.strides,0,avctx->height,yuvjpeg.planes,yuvjpeg.strides)<0){ #endif ms_error("sws_scale() failed."); sws_freeContext(sws_ctx); cleanup(s,avctx, FALSE); freemsg(jpegm); goto end; } sws_freeContext(sws_ctx); av_frame_unref(s->pict); avpicture_fill((AVPicture*)s->pict,(uint8_t*)jpegm->b_rptr,avctx->pix_fmt,avctx->width,avctx->height); packet.data=comp_buf; packet.size=comp_buf_sz; error=avcodec_encode_video2(avctx, &packet, s->pict, &got_pict); if (error<0){ ms_error("Could not encode jpeg picture."); }else{ if (fwrite(comp_buf,packet.size,1,s->file)>0){ ms_message("Snapshot done"); }else{ ms_error("Error writing snapshot."); } } ms_free(comp_buf); cleanup(s,avctx, TRUE); freemsg(jpegm); } goto end; } end: ms_filter_unlock(f); ms_queue_flush(f->inputs[0]); } static MSFilterMethod jpg_methods[]={ { MS_JPEG_WRITER_TAKE_SNAPSHOT, take_snapshot }, { 0,NULL} }; #ifndef _MSC_VER MSFilterDesc ms_jpeg_writer_desc={ .id=MS_JPEG_WRITER_ID, .name="MSJpegWriter", .text="Take a video snapshot as jpg file", .category=MS_FILTER_OTHER, .ninputs=1, .noutputs=0, .init=jpg_init, .process=jpg_process, .uninit=jpg_uninit, .methods=jpg_methods }; #else MSFilterDesc ms_jpeg_writer_desc={ MS_JPEG_WRITER_ID, "MSJpegWriter", "Take a video snapshot as jpg file", MS_FILTER_OTHER, NULL, 1, 0, jpg_init, NULL, jpg_process, NULL, jpg_uninit, jpg_methods }; #endif MS_FILTER_DESC_EXPORT(ms_jpeg_writer_desc)
static void generic_plc_preprocess(MSFilter *f) { generic_plc_struct *mgps=(generic_plc_struct*)f->data; mgps->continuity_buffer = ms_malloc0(mgps->rate*sizeof(int16_t)*TRANSITION_DELAY/1000); /* continuity buffer introduce a 2ms delay */ }