pj_sockaddr_get_len:断言`a-> addr.sa_family == PJ_AF_INET || a-> addr.sa_family == PJ_AF_INET6'失败。中止(核心倾倒)

时间:2018-05-25 20:44:31

标签: pjsip

我正在研究RTP API,它包括在我的PC和目标之间通过RTP发送音频WAV文件。

我有一个问题,发送给我sock_common.c;我使用gdb来找到如何修复这个bug,但我无法解决这个问题。

4:48:46.482          strm0x1386e58  VAD temporarily disabled
14:48:46.483                  rtp.c  pjmedia_rtp_session_init: ses=0x1390824, default_pt=0, ssrc=0x7f2776b6
14:48:46.483                  rtp.c  pjmedia_rtp_session_init: ses=0x1390e44, default_pt=0, ssrc=0x7f2776b6
streamutil: ../src/pj/sock_common.c:393: pj_sockaddr_get_len: Assertion `a->addr.sa_family == PJ_AF_INET || a->addr.sa_family == PJ_AF_INET6' failed.
Aborted (core dumped)

如果您可以帮我修复此错误,请查找附上我的代码。

1 个答案:

答案 0 :(得分:0)

#include <pjmedia/rtp.h>
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#include <pjmedia/codec.h>
#include <pjmedia/stream.h>
#include <pjmedia/port.h>
#include <pjsip.h>
#include <pjsip_simple.h>
#include <pjsip_ua.h>
#include <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h> 
#include <stdlib.h>
#include <string.h>

#define THIS_FILE       "audiotxrtp.c"
#define true 1
#define false 0

#define PJ_INET_ADDRSTRLEN  16
#define ALL_ADDRESSES "0.0.0.0" 
#define LOCAL_ADDRESS "127.0.0.1" 
#define REMOTE_ADDRESS "192.168.2.2" 
#define STREAMMEDIA_SAMPLE_PER_FRAME 160 
#define MAX_RTP_PAYLOAD_LENGHT 160  
#define MAX_RTP_PACKET_SIZE 200 
#define DEFAULT_RTP_PORT    4000 
#define PTIME       20 


typedef struct RtpSessionCtx_t
{

pjmedia_rtp_session     pjInRtpSess;      
pjmedia_rtp_session     pjOutRtpSess;    
pjmedia_port            *play_file_port;  
pjmedia_port *stream_port; 
pjmedia_master_port *master_port; 
pjmedia_snd_port        *snd_port;  
pjmedia_transport*      pjTransportPtr;     
pjmedia_aud_dev_index dev_idx;  
pjmedia_frame play_frame; 
pjmedia_stream *stream; 
pjmedia_stream_info info;
pjmedia_sock_info   sock_info;
pjmedia_codec_info *codec_info; 
pjmedia_codec_param codec_param;                               
pjmedia_dir dir; 
pj_caching_pool         pjCp;               
pj_pool_t               *pool; 
pjmedia_endpt*          pjMedEndptPtr;   

}RtpSessionCtx_t;
static RtpSessionCtx_t RtpSession;

static pj_status_t init_codecs(pjmedia_endpt *med_endpt)
{
return pjmedia_codec_register_audio_codecs(med_endpt, NULL);
}

static int rtptest(char *argv[])
{


pj_status_t status;
pj_log_push_indent(); 
pj_sockaddr_in remoteAddr;  
pj_uint16_t remotePort;
pj_uint16_t localPort=DEFAULT_RTP_PORT;  
RtpSession.play_file_port = NULL;
RtpSession.master_port = NULL;
RtpSession.stream = NULL;
pj_str_t remoteAddressStr; 
pj_timestamp t0,t1;
char rem_addr_str[PJ_INET_ADDRSTRLEN];

enum pjmedia_transport_udp_options
{
/**
 * Normally the UDP transport will continuously check the source address
 * of incoming packets to see if it is different than the configured
 * remote address, and switch the remote address to the source address
 * of the packet if they are different after several packets are
 * received.
 * Specifying this option will disable this feature.
 */
PJMEDIA_UDP_NO_SRC_ADDR_CHECKING = 1
};

pj_bzero(&RtpSession.info.rem_addr.ipv4
        ,sizeof(&RtpSession.info.rem_addr.ipv4));

status =pj_sockaddr_in_init(&RtpSession.info.rem_addr.ipv4
                            ,(const pj_str_t*)&remoteAddressStr,remotePort); 
if (status != PJ_SUCCESS) 
{
  pjsua_perror(THIS_FILE,"Unable to resolve IP interface--Invalid remote 
  address",status); 
  goto on_error; 
}
/* Encoding (outgoing to network) stream as known as capture */
 RtpSession.dir=PJMEDIA_DIR_ENCODING; 
/* Verify arguments. */

if (RtpSession.dir & PJMEDIA_DIR_ENCODING) 
{
    if (RtpSession.info.rem_addr.ipv4.sin_addr.s_addr == 0) 
    {
        printf("Error: remote address must be set\n");
        return 1;     
    }
 }   

 if (argv[1] != NULL && RtpSession.dir != PJMEDIA_DIR_ENCODING)
 {
        printf("Direction is set to --send-only because of --play-file\n");
        RtpSession.dir = PJMEDIA_DIR_ENCODING;
 }    

/* initializing the cache pool  the pools will exploit the entire cache 3=0  
*/

 pj_caching_pool_init(&RtpSession.pjCp, &pj_pool_factory_default_policy, 0);

/* create the media endpoint/socket instance and initialize audio subsystem 
  --card sounds PC
    via Alsa
*/

status = pjmedia_endpt_create(&RtpSession.pjCp.factory, NULL, 1, 
                              &RtpSession.pjMedEndptPtr);       
if (status == PJ_SUCCESS)
{
    puts("\nRTP creation endpoint Successfully \n");
}
else
{
  pjsua_perror(THIS_FILE,"RTP endpoint creation failure\n", status); 
  goto on_error; 
}

/* Register all known audio codecs implemented in PJMEDA-CODEC 
             library to the specified media endpoint.          */    


status = init_codecs(RtpSession.pjMedEndptPtr);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

pjmedia_codec_mgr_get_codec_info(pjmedia_endpt_get_codec_mgr
                                (RtpSession.pjMedEndptPtr),0
                               ,(const pjmedia_codec_info**) 
                                &RtpSession.codec_info); 



/* creating a memory pool for playing file  */  

RtpSession.pool = pj_pool_create( &RtpSession.pjCp.factory, // pool factory     

                                "wav",       /* pool name.           */
                                4000,        /* init size 4096 bytes */
                                4000,        /* increment size       */
                                NULL);       /* callback on error    */

if(RtpSession.pool==NULL)
{
    puts("Unable to create memory pool for playing file");
}
else
{
     puts("create memory pool for playing file Successful\n"); 
}

/* Create stream based on program arguments */ 

RtpSession.pjTransportPtr=NULL;

/* Initialize stream info  Format RTP header formats */

RtpSession.info.type = PJMEDIA_TYPE_AUDIO;
/* RTP using Audio/Video profile -- PJMEDIA_TP_PROTO_RTP_SAVP Secure RTP  */
RtpSession.info.proto = PJMEDIA_TP_PROTO_RTP_AVP; 
RtpSession.info.dir = RtpSession.dir;
/*fmt.clock_rate=8000;fmt.channel=1;fmt.type = PJMEDIA_TYPE_AUDIO;
fmt.encoding_name = "PCMU"*/
pj_memcpy(&RtpSession.info.fmt, RtpSession.codec_info, 
          sizeof(pjmedia_codec_info));

    /* Get codec default param for info                  */
status = pjmedia_codec_mgr_get_default_param(
                pjmedia_endpt_get_codec_mgr(RtpSession.pjMedEndptPtr), 
                RtpSession.codec_info,&RtpSession.codec_param); 

 /* Should be ok, as create_stream() above succeeded */
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


/* Outgoing codec paylaod type -- PCMU */
RtpSession.info.tx_pt = RtpSession.codec_info->pt;
 /* Incoming codec paylaod type -- PCMU */
RtpSession.info.rx_pt = RtpSession.codec_info->pt;
/*Outgoing pt for telephone-events=0 Outgoing codec max ptime=0
 Incoming pt for telephone-events=0
*/
/* RTP SSRC could be arbitrary  
 */
RtpSession.info.ssrc = 1234;
/* Initial RTP timestamp=0 Initial RTP sequence number=0 
 rtp_seq_ts_set->Bitmask flags if initial RTP sequence and/or timestamp for 
 sender are set. 
 bit 0/LSB : sequence flag bit 1 : timestamp flag 
 Jitter buffer init delay 0 msec
 Jitter buffer minimum prefetch delay=0msec
 Jitter buffer maximum prefetch delay 0 msec
 Jitter buffer max delay 0 msec
 Disable automatic sending of RTCP SDES and BYE=0
 use_ka?
 */


/* If remote address is not set -- unspecified family adress, set to an 
   arbitrary address
 * (otherwise stream will assert). remote port=0  PJ_AF_UNSPEC loopback
 */
if (RtpSession.info.rem_addr.addr.sa_family == PJ_AF_UNSPEC) 
{
    const pj_str_t remoteAddrStr = pj_str("127.0.0.1");

    pj_sockaddr_in_init(&RtpSession.info.rem_addr.ipv4, &remoteAddrStr, 0);

    printf("Remote adress and Port are set to %s:%d\n",
           pj_inet_ntop2(PJ_AF_INET, 
           &RtpSession.info.rem_addr.ipv4.sin_addr, rem_addr_str           
           ,sizeof(rem_addr_str))
           ,pj_ntohs(RtpSession.info.rem_addr.ipv4.sin_port));                
    }

     status = pjmedia_transport_udp_create(RtpSession.pjMedEndptPtr, NULL, 
                                   localPort,0, &RtpSession.pjTransportPtr);


     if (status == PJ_SUCCESS)
    {
      puts("UDP Socket Bind Successfully\n");

    /* Log Media Transport */
  puts("======== Media transport info ========\n");

  pjmedia_transport_info tpinfo;
  char addr_buf[80];
  /* Initialize transport info */
  pjmedia_transport_info_init(&tpinfo);

 /* Get media transport info from the specified transport and all underlying 
   transports if any
   The transport also contains information about socket info which describes 
   the local address 
 of the  transport, and would be needed for example to fill in the "c=" and 
   "m=" line of local 
    SDP
 */
   pjmedia_transport_get_info(RtpSession.pjTransportPtr, &tpinfo);

  /* The RTP socket handle =3
   Address to be advertised as the local address for the RTP socket, which 
   does not need to be equal 
  as the bound address (for example, this address can be the address 
  resolved with STUN). 
 */

  PJ_LOG(3,(THIS_FILE,"\n\n%s: %s\n",
           (pjsua_var.media_cfg.enable_ice ? "ICE" : "UDP"),               
           pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name
          ,addr_buf,sizeof(addr_buf),3)));
  }

   else
  {
   pjsua_perror(THIS_FILE, " media transport failed ",status); 
   pjmedia_transport_close(RtpSession.pjTransportPtr );
   return status;
  }


 /* Now that the stream info is initialized, we can create the 
   stream.
  session establishment 
 */

 status = pjmedia_stream_create(RtpSession.pjMedEndptPtr, RtpSession.pool, 
                               &RtpSession.info, 
                               RtpSession.pjTransportPtr, 
                               NULL, &RtpSession.stream);

 if (status != PJ_SUCCESS) 
 {
  pjsua_perror(THIS_FILE,"Error creating stream",status); 
  pjmedia_transport_close(RtpSession.pjTransportPtr );
  return status;
 }

  /* Get the port interface of the stream             */
  status = pjmedia_stream_get_port(RtpSession.stream, 
                                   &RtpSession.stream_port);

  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

  /* Create file media port from the WAV file        */
status = pjmedia_wav_player_port_create(RtpSession.pool, // memory pool            
                                                argv[1], // file to play           
                                                     20, // wav_ptime ptime.     
                                                      0, // flags play whole  
                                                     -1, // 0 default buffer   
                                         &RtpSession.play_file_port); 

 if (status == PJ_SUCCESS)
 {
  puts("opening WAV file port");
 }
 else
 {
  pjsua_perror(THIS_FILE, "Impossible to create wav file port --Unable to 
               use file", status);      
  goto on_error; 
}

 /* Create bridge   */

status = pjmedia_master_port_create(RtpSession.pool, 
                                    RtpSession.play_file_port, 
                                    RtpSession.stream_port, 0, 
                                    &RtpSession.master_port);

if (status != PJ_SUCCESS)
{
    pjsua_perror(THIS_FILE, "Unable to create master port", status); 
    goto on_error;     
} 

status = pjmedia_master_port_start(RtpSession.master_port);

if (status != PJ_SUCCESS) 
{
    pjsua_perror(THIS_FILE, "Error starting master port",status); 
    goto on_error;       
}

 printf("Playing from WAV file %s..\n", argv[1]);


 /* Acquire high resolution timer value. The time value are stored  in 
   cycles*/
 pj_get_timestamp(&t0);

/* Start streaming */
 pjmedia_stream_start(RtpSession.stream);

 printf("Stream is active, dir is send-only, sending to %s:%d\n",
       pj_inet_ntop2(PJ_AF_INET, &remoteAddr.sin_addr, 
       rem_addr_str,sizeof(rem_addr_str)),                  
       pj_ntohs(remoteAddr.sin_port));

 pj_get_timestamp(&t1);
 PJ_LOG(3,(THIS_FILE, "Completed in %u msec\n", pj_elapsed_msec(&t0, &t1))); 

return 0;

on_error:
  pj_log_pop_indent(); //log en pop / avec identation à gauche PJ_LOG_INDENT
return status;
}

  int main(int argc, char *argv[])
  {

   pj_status_t status;
   char tmp[10];

   if (argc != 3) 
  {
     puts("Error: filename and remote adress required");
     puts(DescriptionPtr);
     return 1;
  }

  /* Initializing the PJLIB library before using it */
   status =pj_init();
   PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    puts("\n======== Start Audio implementation Test (audiotxrtp) 
          ========\n");


    rtptest(argv);
   //  pj_thread_sleep(10000); // sleep 10 s  /* Sleep to allow log messages 
    to   flush */




  /* Without this sleep, Windows/DirectSound will repeteadly
   * play the last frame during destroy.
   */
   pj_thread_sleep(100);


  printf("Playing %s \n", argv[1]);
  puts("");
  puts("Press <ENTER> to stop playing and quit");

  if (fgets(tmp, sizeof(tmp), stdin) == NULL) 
  {
    puts("EOF while reading stdin, will quit now..");
  }


   /* Start deinitialization: */


  /* Destroy master port */

  pjmedia_master_port_destroy(RtpSession.master_port, PJ_TRUE);
  RtpSession.play_file_port = NULL;
  RtpSession.stream = NULL;

  /* Destroy stream */
  if (RtpSession.stream) 
  {
    pjmedia_transport *tp;
    tp = pjmedia_stream_get_transport(RtpSession.stream);
    pjmedia_stream_destroy(RtpSession.stream);
    pjmedia_transport_close(tp); //app no ​​longer needs media transport
  }


  status = pjmedia_port_destroy( RtpSession.play_file_port);
  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

  pj_pool_release( RtpSession.pool );

  pjmedia_endpt_destroy( RtpSession.pjMedEndptPtr );

  pj_caching_pool_destroy( &RtpSession.pjCp );

  /* Arrêt PJLIB */
  pj_shutdown();

   return true; 
  }