app crashing while calling number by using SIP - ios

I am doing iOS app which supports calling to numbers (mobile and landlines). Regarding this feature i integrated SIP (Session Initiate Protocol). Its working good. But sometimes while calling time my app getting crashing in following line
status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, NULL, call_id);
and the above line initiated in following method:
pj_status_t sip_dial_with_uri(pjsua_acc_id acc_id, const char *uri, pjsua_call_id *call_id)
{
pj_status_t status = PJ_SUCCESS;
pj_str_t pj_uri;
PJ_LOG(5,(THIS_FILE, "Calling URI \"%s\".", uri));
status = pjsua_verify_sip_url(uri);
if (status != PJ_SUCCESS)
{
PJ_LOG(1,(THIS_FILE, "Invalid URL \"%s\".", uri));
pjsua_perror(THIS_FILE, "Invalid URL", status);
return status;
}
pj_uri = pj_str((char *)uri);
NSLog(#"***check point for assert, acc_id:%d, uri:%s, call_id:%d", (int)acc_id, uri, *call_id);
status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, NULL, call_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error making call", status);
}
return status;
}
if anyone used this API sofar, please provide your valuable suggestions!! Thanks

Related

iOS 13.1.3 VTDecompressionSessionDecodeFrame can't decode right

CVPixelBufferRef outputPixelBuffer = NULL;
CMBlockBufferRef blockBuffer = NULL;
void* buffer = (void*)[videoUnit bufferWithH265LengthHeader];
OSStatus status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
buffer,
videoUnit.length,
kCFAllocatorNull,
NULL, 0, videoUnit.length,
0, &blockBuffer);
if(status == kCMBlockBufferNoErr) {
CMSampleBufferRef sampleBuffer = NULL;
const size_t sampleSizeArray[] = {videoUnit.length};
status = CMSampleBufferCreateReady(kCFAllocatorDefault,
blockBuffer,
_decoderFormatDescription ,
1, 0, NULL, 1, sampleSizeArray,
&sampleBuffer);
if (status == kCMBlockBufferNoErr && sampleBuffer && _deocderSession) {
VTDecodeFrameFlags flags = 0;
VTDecodeInfoFlags flagOut = 0;
OSStatus decodeStatus = VTDecompressionSessionDecodeFrame(_deocderSession,
sampleBuffer,
flags,
&outputPixelBuffer,
&flagOut);
if(decodeStatus == kVTInvalidSessionErr) {
NSLog(#"IOS8VT: Invalid session, reset decoder session");
} else if(decodeStatus == kVTVideoDecoderBadDataErr) {
NSLog(#"IOS8VT: decode failed status=%d(Bad data)", decodeStatus);
} else if(decodeStatus != noErr) {
NSLog(#"IOS8VT: decode failed status=%d", decodeStatus);
}
CFRelease(sampleBuffer);
}
CFRelease(blockBuffer);
}
return outputPixelBuffer;
This is my code to decode the stream data.It was working good on iPhone 6s,but when the code running on iPhoneX or iphone11, the "outputPixelBuffer" return a nil. Can anyone help?
Without seeing the code for your decompressionSession creation, it is hard to say. It could be that your decompressionSession is providing the outputBuffer to the callback function provided at creation, so I highly recommend you add that part of your code too.
By providing &outputPixelBuffer in:
OSStatus decodeStatus = VTDecompressionSessionDecodeFrame(_deocderSession,
sampleBuffer,
flags,
&outputPixelBuffer,
&flagOut);
only means that you've provided the reference, it does not mean that it will be synchronously filled for certain.
I also recommend that you print out the OSStatus for:
CMBlockBufferCreateWithMemoryBlock
and
CMSampleBufferCreateReady
And if there's issues at those steps, there should be a way to know.

PJSip : Not able to unhold the hold call

Getting this error while unholding a call using pjsip.
Unable to create re-INVITE: Invalid operation (PJ_EINVALIDOP)
[status=70013]
Error hanging up call: Invalid operation (PJ_EINVALIDOP) [status=70013]
Using this code for untold
pj_status_t pj_wrapper_unhold_call(pjsua_call_id call_id, char deviceId, char groupId, char *token) {
pj_status_t status;
if (!pj_wrapper_initialized) {
return PJ_EGONE;
}
status = pjsua_call_reinvite(call_id, PJSUA_CALL_UNHOLD, NULL);
if (status != PJ_SUCCESS) {
pj_wrapper_show_error("Error hanging up call", status);
}
return status;
}

How to change the pjsip register account at the time of re-registration?

I am working on with pjsip for iOS, I have configured the pjsip and able to register and reregister for specific time interval, but there is a scenario where I want to change the pjsip account details at the time of re register with new details but I havent found anything on google which can guide how to change it.
If someone have a idea about this please guide me through how to change the pjsua_acc_config details at time of re registration, I get the method call at the time of re registration.
static void on_reg_state2(pjsua_acc_id acc_id, pjsua_reg_info *info) {
PJ_LOG(3,(__FILE__, "%s: Account %d Reason %.*s Status %d code %d CurrentOp %d",
__FUNCTION__, acc_id, info->cbparam->reason.slen, info->cbparam->reason.ptr,
info->cbparam->status,info->cbparam->code, info->cbparam->regc));
}
get account configuration for account id, and set the fields to whatever required in on_reg_state2 function.
if (pjsua_acc_is_valid(acc_id))
{
pjsua_acc_set_default(acc_id);
pjsua_acc_config acc_cfg;
pj_status_t status;
pjsua_acc_config_default(&acc_cfg);
acc_cfg.id = pj_str(id);
acc_cfg.reg_uri = pj_str(registrar);
acc_cfg.cred_count = 1;
acc_cfg.cred_info[0].scheme = pj_str("Digest");
acc_cfg.cred_info[0].realm = pj_str(realm);
acc_cfg.cred_info[0].username = pj_str(uname);
acc_cfg.cred_info[0].data_type = 0;
acc_cfg.cred_info[0].data = pj_str(passwd);
acc_cfg.publish_enabled = PJ_TRUE;
}
Its like same as re register.
remove current account and add new one
if (_sip_acc_id != PJSUA_INVALID_ID){
// pjsua_acc_info info;
// pjsua_acc_get_info(_sip_acc_id, &info);
//
// if (info.has_registration){
pj_status_t statusDelete = pjsua_acc_del(_sip_acc_id);
if (statusDelete != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error removing new account", status);
[app displayParameterError: #"Error removing new account."];
}
// }
}
status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &_sip_acc_id);
if (status != PJ_SUCCESS)
{
pjsua_perror(THIS_FILE, "Error adding new account", status);
[app displayParameterError: #"Error adding new account."];
}
This is guide for recomendationabout PJSIP You can click this PJSIP

PJSIP no audio on iPad

I have been working on a SIP client for iOS using PJSIP. Everything works great on iPhone all the models. But on iPad and iPod Touch the audio is not heard from the speakers of the iPad or the iPod Touch. The code works great for iPhone speakers. Since iPad and iPod do not have earpiece no audio is coming out from the SIP call from the speakers. Anyone who can let me know what could be wrong with the iPad implementation ? Here is the code that might help:
// Start and register sip account
int startPjsip(char sipUser, char sipDomain, char* scheme, char* realm, char* username, int dataType, char* passwd, char* proxy, char* protocol)
{
pj_status_t status;
pj_log_set_level(5);
// Create pjsua first
status = pjsua_create();
if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
// Init pjsua
{
// Init the config structure
pjsua_config cfg;
pjsua_config_default (&cfg);
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
cfg.cb.on_reg_state = &on_reg_state;
// Init the logging config structure
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 4;
// Init the pjsua
status = pjsua_init(&cfg, &log_cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
// If outbound proxy is required.
if (proxy) {
cfg.outbound_proxy_cnt = 1;
cfg.outbound_proxy[0] = pj_str(proxy);
}
}
if (strcasecmp(protocol, "UDP") == 0)
{
/* iOS version above iOS 4 do not support UDP in bakground. */
// Add UDP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add UDP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
}
if (strcasecmp(protocol, "TCP") == 0)
{
// Add TCP transport.
{
// Init transport config structure
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
// Add TCP transport.
status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
}
}
// Initialization is done, now start pjsua
status = pjsua_start();
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
// Register the account on local sip server
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
char sipId[MAX_SIP_ID_LENGTH];
sprintf(sipId, "sip:%s#%s", sipUser, sipDomain);
cfg.id = pj_str(sipId);
char regUri[MAX_SIP_REG_URI_LENGTH];
sprintf(regUri, "sip:%s", sipDomain);
cfg.reg_uri = pj_str(regUri);
// Add sip account credentials.
cfg.cred_count = 1;
cfg.cred_info[0].scheme = pj_str(scheme);
cfg.cred_info[0].realm = pj_str(realm);
cfg.cred_info[0].username = pj_str(username);
cfg.cred_info[0].data_type = dataType;
cfg.cred_info[0].data = pj_str(passwd);
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) error_exit("Error adding account", status);
}
return 0;
}
static void on_call_media_state(pjsua_call_id call_id)
{
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
// When media is active, connect call to sound device.
pjsua_conf_connect(ci.conf_slot, 0);
pjsua_conf_connect(0, ci.conf_slot);
pjsua_conf_adjust_rx_level(0, 1);
pjsua_conf_adjust_tx_level(0, 1);
}
PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
(int)ci.state_text.slen,
ci.state_text.ptr));
}

Pass through CMSampleBufferRef data to audio output jack

I am developing one app in which I need to pass through audio capturing through output audio jack at the same time record and save video.
I have looked into aurio touch apple sample code and implemented audio passthrough.
I have also implemented the video recording through AVCaptureSession.
Above both functionality individually done and works pefectly.
But when I merge functionality audio pass through not working because of audio session of the AVCapturesession.
I have also tried to pass through audio data which I am getting from AVCaptureSession delegate methods. Below is my code :
OSStatus err = noErr;
AudioBufferList audioBufferList;
CMBlockBufferRef blockBuffer;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
CMItemCount numberOfFrames = CMSampleBufferGetNumSamples(sampleBuffer); // corresponds to the number of CoreAudio audio frames
currentSampleTime += (double)numberOfFrames;
AudioTimeStamp timeStamp;
memset(&timeStamp, 0, sizeof(AudioTimeStamp));
timeStamp.mSampleTime = currentSampleTime;
timeStamp.mFlags |= kAudioTimeStampSampleTimeValid;
AudioUnitRenderActionFlags flags = 0;
aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate *)[[UIApplication sharedApplication]delegate];
err = AudioUnitRender(self.rioUnit, &flags, &timeStamp, 1, numberOfFrames, &audioBufferList);
if (err) { printf("PerformThru: error %d\n", (int)err); }
But it is giving error. Please advise what can be done further as soon as possible. I have looked into so many docs and so many codes but couldn't find any solution. Please help..
Here's some better error handling code. What error does it return? You can look up the error description by searching for it in the documentation.
static void CheckError (OSStatus error, const char *operation) {
if (error == noErr) return;
char str[20] = {};
// see if it appears to be a 4 char code
*(UInt32*)(str + 1) = CFSwapInt32HostToBig(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
str[0] = str[5] = '\'';
str[6] = '\0';
} else {
sprintf(str, "%d", (int)error);
}
fprintf(stderr, "Error: %s(%s)\n", operation, str);
exit(1);
}
- (void)yourFunction
{
AudioBufferList audioBufferList;
CMBlockBufferRef blockBuffer;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
CMItemCount numberOfFrames = CMSampleBufferGetNumSamples(sampleBuffer); // corresponds to the number of CoreAudio audio frames
currentSampleTime += (double)numberOfFrames;
AudioTimeStamp timeStamp;
memset(&timeStamp, 0, sizeof(AudioTimeStamp));
timeStamp.mSampleTime = currentSampleTime;
timeStamp.mFlags |= kAudioTimeStampSampleTimeValid;
AudioUnitRenderActionFlags flags = 0;
aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate *)[[UIApplication sharedApplication]delegate];
CheckError(AudioUnitRender(self.rioUnit, &flags, &timeStamp, 1, numberOfFrames, &audioBufferList),
"Error with AudioUnitRender");
}

Resources