Hi I have modified simpleua.c sample in order to record audio data from 2 different audio streams. In call_on_media_update() callback I can see that the media count is 2, however I am able to record only the first stream. Below is the code I am using. With 2 audio streams the application always crashes in pjmedia_stream_create(). I have also tried to record separately stream 0 or stream 1, but even in this case stream 1 recording generates the same crash. Can you tell me what I am doing wrong ? thanks Bogdan static void call_on_media_update( pjsip_inv_session *inv, pj_status_t status) { pjmedia_stream_info stream_info[MAX_MEDIA_CNT]; const pjmedia_sdp_session *local_sdp; const pjmedia_sdp_session *remote_sdp; pjmedia_port *media_port[MAX_MEDIA_CNT]; PJ_LOG(3, (THIS_FILE, "call_on_media_update")); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "SDP negotiation has failed", status); /* Here we should disconnect call if we're not in the middle * of initializing an UAS dialog and if this is not a re-INVITE. */ return; } /* Get local and remote SDP. * We need both SDPs to create a media session. */ status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp); const unsigned int local_media_count = local_sdp->media_count; status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp); const unsigned int remote_media_count = remote_sdp->media_count; PJ_LOG(3, (THIS_FILE, "Media count: local %d, remote %d", local_media_count, remote_media_count)); if ((MAX_MEDIA_CNT < local_media_count) || (MAX_MEDIA_CNT < remote_media_count)) { app_perror(THIS_FILE, "Either local or remote media count exceed the maximum media count", status); return; } for (unsigned int stream_index = 0; stream_index < local_media_count; ++stream_index) { PJ_LOG(3, (THIS_FILE, "Audio stream #%d", stream_index)); /* Create stream info based on the media audio SDP. */ PJ_LOG(3, (THIS_FILE, "pjmedia_stream_info_from_sdp")); status = pjmedia_stream_info_from_sdp(&(stream_info[stream_index]), inv->dlg->pool, g_med_endpt, local_sdp, remote_sdp, stream_index); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create audio stream info", status); return; } /* If required, we can also change some settings in the stream info, * (such as jitter buffer settings, codec settings, etc) before we * create the stream. */ /* Create new audio media stream, passing the stream info, and also the * media socket that we created earlier. */ PJ_LOG(3, (THIS_FILE, "pjmedia_stream_create")); status = pjmedia_stream_create(g_med_endpt, inv->dlg->pool, &(stream_info[stream_index]), g_med_transport[stream_index], NULL, &(g_med_stream[stream_index])); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create audio stream", status); return; } /* Start the audio stream */ PJ_LOG(3, (THIS_FILE, "pjmedia_stream_start")); status = pjmedia_stream_start(g_med_stream[stream_index]); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to start audio stream", status); return; } /* Get the media port interface of the audio stream. * Media port interface is basicly a struct containing get_frame() and * put_frame() function. With this media port interface, we can attach * the port interface to conference bridge, or directly to a sound * player/recorder device. */ PJ_LOG(3, (THIS_FILE, "pjmedia_stream_get_port")); status = pjmedia_stream_get_port(g_med_stream[stream_index], &(media_port[stream_index])); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to get stream port", status); return; } /* Get clock rate of the media port */ pjmedia_audio_format_detail *u_afd = pjmedia_format_get_audio_format_detail(&(media_port[stream_index]->info.fmt), PJ_TRUE); const unsigned int clock_rate = u_afd->clock_rate; /* Get samples/frame */ const unsigned int spf = PJMEDIA_PIA_SPF(&(media_port[stream_index]->info)); /* Get channel count */ const unsigned int channel_count = u_afd->channel_count; /* Get bits /sample */ const unsigned int bps = u_afd->bits_per_sample; PJ_LOG(3, (THIS_FILE, "media params: clock rate %d, samp/frame %d, channel count %d, bits/samp %d", clock_rate, spf, channel_count, bps)); /* Create WAVE file writer port. */ PJ_LOG(3, (THIS_FILE, "pjmedia_wav_writer_port_create")); char filename[1024]; sprintf_s(filename, sizeof(filename), "simple_ua%d.wav", stream_index); status = pjmedia_wav_writer_port_create(inv->pool, filename, clock_rate, channel_count, spf, bps, 0, 0, &(g_file_port[stream_index])); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to open WAV file for writing", status); return; } /* record stream to wave file */ PJ_LOG(3, (THIS_FILE, "pjmedia_master_port_create")); status = pjmedia_master_port_create(g_pool, media_port[stream_index], g_file_port[stream_index], 0, &(g_master_port[stream_index])); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create master port", status); return; } PJ_LOG(3, (THIS_FILE, "pjmedia_master_port_start")); status = pjmedia_master_port_start(g_master_port[stream_index]); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Error starting master port", status); return; } } /* Done with media. */ PJ_LOG(3, (THIS_FILE, "Done with media")); } Bogdan Cristea tél. portable: +40 (751) 705 754 tél. fixe: +40 (371) 783 139 ID skype: bogdan.cristea77 |
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org