Receive audio data from 2 different streams

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux