// // Created by lilin on 2019-12-10. // #include "BaresipObj.h" BaresipObj::BaresipObj(JavaListener *javaListener) { this->javaListener = javaListener; } BaresipObj::~BaresipObj() { } static void dtmf_handler(struct call *call, char key, void *arg){ LOGE("收到key=%c",key); } static void ua_exit_handler(void *arg) { (void)arg; LOGD("ua exited -- stopping main runloop\n"); re_cancel(); } static void ua_event_handler( ua *ua, enum ua_event ev, struct call *call, const char *prm, void *arg) { player *player = baresip_player(); BaresipObj *baresip = (BaresipObj *)(arg); const char * str= uag_event_str(ev); LOGE( "event_str==%s" ,str); baresip->javaListener->onBaresipState( str); switch (ev) { case UA_EVENT_REGISTERING: case UA_EVENT_UNREGISTERING: case UA_EVENT_REGISTER_OK: if(ev==UA_EVENT_REGISTER_OK){ char codec[100]=""; list * a= baresip_aucodecl(); struct le *le;int num=0; for (le = list_head(a); numnext){ aucodec *ac =(aucodec *) le->data; strcat(codec,ac->name);strcat(codec,",");num++; } strcat(codec,"="); list * c = baresip_vidcodecl();num=0; for (le = list_head(c); numnext) { vidcodec *ac = (vidcodec *)le->data; strcat(codec,ac->name);strcat(codec,",");num++; } baresip->javaListener->onBaresipCodec( codec); } break; case UA_EVENT_REGISTER_FAIL: break; case UA_EVENT_CALL_INCOMING: baresip->barecall=call; (void)play_file(&baresip->bareplay, player, "ring.wav", 5); break; case UA_EVENT_CALL_RINGING: break; case UA_EVENT_CALL_PROGRESS: break; case UA_EVENT_CALL_ESTABLISHED: mem_deref(baresip->bareplay); baresip->bareplay =NULL; LOGE("收到set key="); //call_set_handlers( call, NULL, dtmf_handler, NULL); break; case UA_EVENT_CALL_MENC: break; case UA_EVENT_CALL_TRANSFER: break; case UA_EVENT_CALL_TRANSFER_FAILED: break; case UA_EVENT_CALL_CLOSED: mem_deref(baresip->bareplay); baresip->bareplay =NULL; baresip->javaListener->onBaresipVstop(); baresip->barecall= NULL; break; case UA_EVENT_AUDIO_ERROR: mem_deref(call); baresip->barecall= NULL; goto out; default: goto out; } out: return; } static void net_debug_log() { char debug_buf[2048]; int l; l = re_snprintf(&(debug_buf[0]), 2047, "%H", net_debug, baresip_network()); if (l != -1) { debug_buf[l] = '\0'; LOGD("1.%s\n", debug_buf); } } static void ua_print_sip_status_log() { char debug_buf[2048]; int l; l = re_snprintf(&(debug_buf[0]), 2047, "%H", ua_print_sip_status); if (l != -1) { debug_buf[l] = '\0'; LOGD("2.%s\n", debug_buf); } } //////////////////////// struct vidsrc_st { const struct vidsrc *vs; /* inheritance */ pthread_t thread; bool run; struct vidsz sz; vidsrc_frame_h *frameh; void *arg; FrameQueue *frameQueue=NULL; }; BaresipObj *xbaresipObj=NULL; static struct vidsrc *mod_avf; static void destructorsrc(void *arg) { vidsrc_st *st = (vidsrc_st *)arg; st->frameQueue->notifyQueue(); st->frameQueue->clearQueue(); st->frameQueue=NULL; if (st->run) { st->run = false; pthread_join(st->thread, NULL); } } static void *read_thread(void *data) { struct vidsrc_st *st =(struct vidsrc_st *) data; int64_t pts; uint64_t timestamp; unsigned i; while (st->run) { if( st->frameQueue==NULL ){ break;} AVFrame *frame=st->frameQueue->getAvFrame(); if( frame==NULL ){ continue;} struct vidframe vf; vf.fmt =VID_FMT_YUV420P; st->sz.w=frame->width ;st->sz.h=frame->height; vf.size =st->sz; for (i=0; i<4; i++) { vf.data[i] = frame->data[i]; vf.linesize[i] = frame->linesize[i]; } pts = frame->pts; timestamp = pts * VIDEO_TIMEBASE * 1 / 25; // LOGE("当前pts==%lld",pts); st->frameh(&vf, timestamp, st->arg); if (frame) { av_frame_free(&frame); } } LOGE("停止"); return NULL; } static int allocsrc(struct vidsrc_st **stp, const struct vidsrc *vs, struct media_ctx **mctx, struct vidsrc_prm *prm, const struct vidsz *size, const char *fmt, const char *dev, vidsrc_frame_h *frameh, vidsrc_error_h *errorh, void *arg) { vidsrc_st *st; uint32_t i; int ret, err = 0; double input_fps = 0; (void)mctx; (void)fmt; (void)errorh; if (!stp || !vs || !prm || !size || !frameh) return EINVAL; st = static_cast(mem_zalloc(sizeof(*st), destructorsrc)); if (!st) return ENOMEM; if(xbaresipObj->frameQueue==NULL){xbaresipObj->frameQueue = new FrameQueue();} //需要发送开始send st->frameQueue= xbaresipObj->frameQueue; st->vs = vs; st->sz = *size; st->frameh = frameh; st->arg = arg; st->sz.w =640; st->sz.h =480; st->run = true; err = pthread_create(&st->thread, NULL, read_thread, st); if (err) { st->run = false; goto out; } //set //g_ctx.st=st; out: if (err) mem_deref(st); else *stp = st; return err; } struct vidisp_st { const struct vidisp *vd; /**< Inheritance (1st) */ struct vidsz size; }; static struct vidisp *vid; static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame, uint64_t timestamp) { AVFrame *avFrame = av_frame_alloc(); for (int i=0; i<4; i++) { avFrame->data[i]=frame->data[i] ; avFrame->linesize[i]=frame->linesize[i] ; } int width=frame->size.w,height=frame->size.h; uint8_t *t= avFrame->data[0]; xbaresipObj->javaListener->onBaresipVyuv( width,height,avFrame->data[0],avFrame->data[1],avFrame->data[2]); av_frame_free(&avFrame); av_free(avFrame); avFrame=NULL; return 0; } static void hide(struct vidisp_st *st) { if (!st) return; } static void destructordispl(void *arg) { } static int allocdispl(struct vidisp_st **stp, const struct vidisp *vd, struct vidisp_prm *prm, const char *dev, vidisp_resize_h *resizeh, void *arg) { struct vidisp_st *st; st = static_cast(mem_zalloc(sizeof(*st), destructordispl)); if (!st) return ENOMEM; st->vd = vd; *stp = st; return 0; } ////////////729//////////////// struct g729_aucodec { struct aucodec ac; uint32_t bitrate; }; int g729_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt, bool offer, void *arg) { const struct g729_aucodec *g729 = static_cast(arg); (void)offer; if (!mb || !fmt || !g729) return 0; return mbuf_printf(mb, "a=fmtp:%s bitrate=%u\r\n", fmt->id, g729->bitrate); } static uint32_t g729_bitrate(const char *fmtp) { struct pl pl, bitrate; if (!fmtp) return 0; pl_set_str(&pl, fmtp); if (fmt_param_get(&pl, "bitrate", &bitrate)) return pl_u32(&bitrate); return 0; } bool g729_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *arg) { const struct g729_aucodec *g729 = static_cast(arg); (void)lfmtp; if (!g729) return false; if (g729->bitrate != g729_bitrate(rfmtp)) return false; return true; } struct auenc_state { bcg729EncoderChannelContextStruct *encoder; }; static void g729_encode_updatedestructor(void *arg) { struct auenc_state *aes = static_cast(arg); closeBcg729EncoderChannel(aes->encoder); } int g729_encode_update(struct auenc_state **aesp, const struct aucodec *ac, struct auenc_param *prm, const char *fmtp) { struct auenc_state *aes; (void)prm; (void)fmtp; if (!aesp || !ac) return EINVAL; aes = *aesp; if (aes) return 0; aes = static_cast(mem_alloc(sizeof(*aes), g729_encode_updatedestructor)); if (!aes) return ENOMEM; aes->encoder = initBcg729EncoderChannel(0); *aesp = aes; LOGE("729编码init1"); return 0; } int g729_encode1(struct auenc_state *aes, uint8_t *buf, size_t *len, int fmt, const void *sampv, size_t sampc) { if (!aes || !buf || !len || !sampv) return EINVAL; int16_t *ddp = (int16_t *) sampv; uint8_t *edp = buf; int total_len = 0; while (sampc >= 80) { uint8_t frameSize; bcg729Encoder(aes->encoder, ddp, edp, &frameSize); ddp += 80; sampc -= 80; edp += frameSize; total_len += frameSize; } *len = total_len; return 0; } struct audec_state { bcg729DecoderChannelContextStruct *decoder; }; static void g729_decode_updatedestructor(void *arg) { struct audec_state *ads = static_cast(arg); closeBcg729DecoderChannel(ads->decoder); } int g729_decode_update(struct audec_state **adsp, const struct aucodec *ac, const char *fmtp) { //const struct g729_aucodec *g729 = (struct g729_aucodec *)ac; struct audec_state *ads; (void)fmtp; if (!adsp || !ac) return EINVAL; ads = *adsp; if (ads) return 0; ads = static_cast(mem_alloc(sizeof(*ads), g729_decode_updatedestructor)); if (!ads) return ENOMEM; ads->decoder = initBcg729DecoderChannel( ); *adsp = ads; return 0; } int g729_decode1(struct audec_state *ads, int fmt, void *sampv, size_t *sampc, const uint8_t *buf, size_t len) { //size_t framec; if (!ads || !sampv || !sampc || !buf) return EINVAL; int total_sampc = 0; int16_t *ddp = (int16_t *) sampv; LOGE("====%d",len); while (len >= 10) { bcg729Decoder(ads->decoder, const_cast(buf), 10, 0, 0, 0, ddp ) ; buf += 10; len -= 10; ddp += 80; total_sampc += 80; } *sampc = total_sampc; return 0; } static struct g729_aucodec g729 = { .ac = { .le=LE_INIT, .pt="18", .name = "G729", .srate = 8000, .crate = 8000, .ch = 1, .pch = 1, .encupdh = g729_encode_update, .ench = g729_encode1, .decupdh = g729_decode_update, .dech = g729_decode1, .fmtp_ench = g729_fmtp_enc, .fmtp_cmph = g729_fmtp_cmp, }, .bitrate = 8000 }; /////snd///// //////////////////////////// struct sndfile_enc { struct aufilt_enc_st af; /* base class */ enum aufmt fmt; FILE *file = NULL; }; struct sndfile_dec { struct aufilt_dec_st af; /* base class */ enum aufmt fmt; FILE *file = NULL; }; static void enc_destructor(void *arg) { struct sndfile_enc *st = static_cast(arg); fclose(st->file);LOGE("关闭文件"); list_unlink(&st->af.le); } static void dec_destructor(void *arg) { struct sndfile_dec *st = static_cast(arg); // fclose(st->file);LOGE("关闭文件"); list_unlink(&st->af.le); } static int encodeaudio_update(struct aufilt_enc_st **stp, void **ctx, const struct aufilt *af, struct aufilt_prm *prm, const struct audio *au) { struct sndfile_enc *st; int err = 0; (void)ctx; (void)af; (void)au; if (!stp || !prm) return EINVAL; st = static_cast(mem_zalloc(sizeof(*st), enc_destructor)); if (!st) return EINVAL; st->file=fopen("/data/data/lilin.com/files/2.pcm","wb"); st->fmt = static_cast(prm->fmt); if(st->fmt==AUFMT_S16LE ){ LOGE( "====ok lalal =%d=%d",prm->srate , prm->ch); } *stp = (struct aufilt_enc_st *)st; return err; } static int encodeaudio(struct aufilt_enc_st *st, void *sampv, size_t *sampc) { struct sndfile_enc *sf = (struct sndfile_enc *)st; size_t num_bytes; if (!st || !sampv || !sampc) return EINVAL; // num_bytes = *sampc * aufmt_sample_size(sf->fmt); LOGE("编码写"); fwrite(sampv, *sampc, aufmt_sample_size(sf->fmt) ,sf->file); // LOGE("encodeaudio=%d", num_bytes); return 0; } static int decodeaudio_update(struct aufilt_dec_st **stp, void **ctx, const struct aufilt *af, struct aufilt_prm *prm, const struct audio *au) { struct sndfile_dec *st; int err = 0; (void)ctx; (void)af; (void)au; if (!stp || !prm) return EINVAL; st = static_cast(mem_zalloc(sizeof(*st), dec_destructor)); if (!st) return EINVAL; //st->file=fopen("/data/data/lilin.com/files/1.pcm","wb"); st->fmt = static_cast(prm->fmt); if(st->fmt==AUFMT_S16LE ){ LOGE( "====ok lalal =%d=%d",prm->srate , prm->ch); } *stp = (struct aufilt_dec_st *)st; return err; } static int decodeaudio(struct aufilt_dec_st *st, void *sampv, size_t *sampc) { struct sndfile_dec *sf = (struct sndfile_dec *)st; size_t num_bytes; if (!st || !sampv || !sampc) return EINVAL; //num_bytes = *sampc * aufmt_sample_size(sf->fmt); //LOGE("解码写"); //fwrite(sampv, *sampc, aufmt_sample_size(sf->fmt) ,sf->file); //LOGE("decodeaudio=%d", num_bytes); return 0; } static struct aufilt sndfile = { LE_INIT, "sndfile", encodeaudio_update, encodeaudio, decodeaudio_update, decodeaudio }; ///// static void signal_handler(int sig) { static bool term = false; if (term) { mod_close(); exit(0); } term = true; LOGD("liili terminated by signal (%d)\n", sig); ua_stop_all(false); } void *baresipthreadrun(void *arg){ BaresipObj *baresipobj = (BaresipObj *)(arg); avdevice_register_all(); avformat_network_init(); int err; const char *path = "/data/data/lilin.com/files"; //runLoggingThread(); err = libre_init(); if (err) goto out; conf_path_set(path); log_enable_debug(true); err = conf_configure(); if (err) { LOGD("conf_configure() failed: (%d)\n", err); goto out; } err = baresip_init(conf_config()); if (err) { LOGD("baresip_init() failed (%d)\n", err); goto out; } play_set_path(baresip_player(), path); err = ua_init("baresip v", true, true, false); if (err) { LOGD("ua_init() failed (%d)\n", err); goto out; } uag_set_exit_handler(ua_exit_handler, NULL); uag_event_register(ua_event_handler, arg); err = conf_modules(); if (err) { LOGE("conf_modules() failed (%d)\n", err); goto out; } struct le *le; for (le = list_head(uag_list()); le != NULL; le = le->next) { baresipobj->bareua = (struct ua *)le->data; } net_debug_log(); ua_print_sip_status_log(); //reg xbaresipObj=baresipobj; aucodec_register(baresip_aucodecl(), (struct aucodec *)&g729); vidisp_register(&vid, baresip_vidispl(), "opengl", allocdispl, NULL, display, hide); vidsrc_register(&mod_avf, baresip_vidsrcl(), "avformat", allocsrc, NULL); //aufilt_register(baresip_aufiltl(), &sndfile); 声音保存demo baresipobj-> baresipstate=1; LOGD("Running main loop\n"); err = re_main(signal_handler); LOGD("end Running main loop\n"); out: if (err) { LOGE("stopping UAs due to error: (%d)\n", err); ua_stop_all(true); } else { LOGE("main loop exit\n"); } LOGD("closing"); ua_close(); module_app_unload(); conf_close(); baresip_close(); uag_event_unregister(ua_event_handler); LOGD("unloading modules end ..."); // mod_close(); // libre_close(); return 0; } void BaresipObj::startbaresip() { pthread_create(&baresipthread,NULL,baresipthreadrun,this); } void BaresipObj::stopbaresip() { LOGD("unloading modules 111..."); ua_stop_all(true); pthread_join(baresipthread ,NULL); LOGD("unloading modules 222 ..."); //ua_close(); // module_app_unload(); //conf_close(); // baresip_close(); // mod_close(); //libre_close(); } void BaresipObj::baresipreg(const char *sipaddress) { re_thread_enter(); if(bareua!= NULL)ua_destroy(bareua); int err= ua_alloc( &bareua, sipaddress); ua_register(bareua); re_thread_leave(); } void BaresipObj::baresipjie() { re_thread_enter(); if(barecall!=NULL){ mem_deref(bareplay); bareplay=NULL; if(call_has_video(barecall) ){ javaListener->onBaresipVstart(); } ua_answer(bareua, barecall ); } re_thread_leave(); } int BaresipObj::bareisreg() { re_thread_enter(); int state =ua_isregistered(bareua)?1:0; if(state==0){ ua_register(bareua);state=1; LOGE("重新注册了");} re_thread_leave(); return state; } void BaresipObj::baresipgua() { if( barecall !=nullptr ){ re_thread_enter(); ua_hangup(bareua, barecall, 0, NULL); re_thread_leave(); } } int BaresipObj::baresipcall(const char *sipaddress) { int err =-1; if (list_count(ua_calls(bareua)) > 1) { LOGE("YOU TONG HUA!!");return err; } re_thread_enter(); //reset err= ua_connect(bareua,&barecall,NULL,sipaddress,VIDMODE_OFF); re_thread_leave(); return err; } int BaresipObj::baresipcallv(const char *sipaddress) { int err =-1; if (list_count(ua_calls(bareua)) > 1) { LOGE("YOU TONG HUA!!");return err; } re_thread_enter(); //reset err= ua_connect(bareua,&barecall,NULL,sipaddress,VIDMODE_ON); javaListener->onBaresipVstart(); re_thread_leave(); return err; }