Failure: calling pjlib from unknown/external thread

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

 



maybe you can put register thread function inside every functions of your
dll.

regards,
Gang

On Wed, Sep 24, 2008 at 7:12 PM, programmer <programmer at supereva.it> wrote:

> Hi everybody,
>
> I know that the topic was discussed long time ago
> (and many times) but I didn't still find a solution
> to this issue for my project.
>
> I wrote a little Windows standard DLL
> (compiled with VC6 using pjsip ver 0.8.0)
> to stream RTP audio over UDP sockets.
> I use this dll in visual basic 6 projects.
> The problem is that when I start streaming,
> calling the sub "StartStream" mapped in the DLL,
> I get:
>     "Calling pjlib from unknown/external thread. You must "
>     "register external threads with pj_thread_register() "
>     "before calling any pjlib functions."
>
>
> I read I must register the thread but I don't
> know which thread (..sorry i'm bad with threads,
> vb6 don't want the developer familiar with them!)
> and where register it.
> That's the source code of the DLL,
> any contribute will be really appreciated.
>
> Andrea
>
>
>
>
> #include <pjlib.h>
> #include <pjlib-util.h>
> #include <pjmedia.h>
> #include <pjmedia-codec.h>
>
> #include <stdlib.h> /* atoi(): Convert string to integer */
> #include <stdio.h>
>
> #include "util.h"
>
> #define THIS_FILE "pjdll.cpp"
>
>
> #include <string>
> #include <atlbase.h>
>
>
>
> BOOL APIENTRY DllMain( HANDLE hModule,
>                       DWORD  ul_reason_for_call,
>                       LPVOID lpReserved
>      )
> {
>    return TRUE;
> }
>
>
>
>
> /*
>  * Register codecs.
>  */
> static pj_status_t init_codecs(pjmedia_endpt *med_endpt)
> {
>    pj_status_t status;
>
>    /* To suppress warning about unused var when all codecs are disabled */
>    PJ_UNUSED_ARG(status);
>
> #if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
>    status = pjmedia_codec_g711_init(med_endpt);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC!=0
>    status = pjmedia_codec_gsm_init(med_endpt);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
>    status = pjmedia_codec_speex_init(med_endpt, 0, -1, -1);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC!=0
>    status = pjmedia_codec_l16_init(med_endpt, 0);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
>    return PJ_SUCCESS;
> }
>
>
>
>
>
>
>
> /*
>  * Unregister all codecs.
>  */
> static pj_status_t deinit_codecs()
> {
>    pj_status_t status;
>
>    /* To suppress warning about unused var when all codecs are disabled */
>    PJ_UNUSED_ARG(status);
>
> #if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
>    status = pjmedia_codec_g711_deinit();
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC!=0
>    status = pjmedia_codec_gsm_deinit();
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
>    status = pjmedia_codec_speex_deinit();
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
> #if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC!=0
>    status = pjmedia_codec_l16_deinit();
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
> #endif
>
>    return PJ_SUCCESS;
> }
>
>
>
>
>
>
> /*
>  * Create stream based on the codec, dir, remote address, etc.
>  */
> static pj_status_t create_stream( pj_pool_t *pool,
>      pjmedia_endpt *med_endpt,
>      const pjmedia_codec_info *codec_info,
>      pjmedia_dir dir,
>      pj_uint16_t local_port,
>      const pj_sockaddr_in *rem_addr,
>      pjmedia_stream **p_stream )
> {
>    pjmedia_stream_info info;
>    pjmedia_transport *transport = NULL;
>    pj_status_t status;
>
>
>    /* Reset stream info. */
>    pj_bzero(&info, sizeof(info));
>  status = pj_init();
>
>
>    /* Initialize stream info formats */
>    info.type = PJMEDIA_TYPE_AUDIO;
>    info.dir = dir;
>    pj_memcpy(&info.fmt, codec_info, sizeof(pjmedia_codec_info));
>    info.tx_pt = codec_info->pt;
>    info.ssrc = pj_rand();
>
>
>    /* Copy remote address */
>    pj_memcpy(&info.rem_addr, rem_addr, sizeof(pj_sockaddr_in));
>
>
>    /* Create media transport */
>    status = pjmedia_transport_udp_create(med_endpt, NULL, local_port,
>       0, &transport);
>    if (status != PJ_SUCCESS)
>  return status;
>
>
>    /* Now that the stream info is initialized, we can create the
>     * stream.
>     */
>
>    status = pjmedia_stream_create( med_endpt, pool, &info,
>        transport, NULL, p_stream);
>
>    if (status != PJ_SUCCESS) {
>  app_perror(THIS_FILE, "Error creating stream", status);
>  pjmedia_transport_udp_close(transport);
>  return status;
>    }
>
>
>    return PJ_SUCCESS;
> }
>
>
>
>
>
> /*
>  * main()
>  */
>
> pj_caching_pool cp;
> pjmedia_endpt *med_endpt;
> pj_pool_t *pool;
> pjmedia_snd_port *snd_port = NULL;
> pjmedia_stream *stream = NULL;
> pjmedia_port *stream_port = NULL;
> pj_status_t status;
>
>
>
> extern "C" __declspec(dllexport) int __stdcall StartStream(long LocalPort,
> LPSTR strRemoteIP, long RemotePort)
> {
>    /* Default values */
>    const pjmedia_codec_info *codec_info = NULL;
>    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
>    pj_sockaddr_in remote_addr;
>    pj_uint16_t local_port = 4000;
>    char *codec_id = NULL;
>
>
>    pj_bzero(&remote_addr, sizeof(remote_addr));
>
>
>    /* init PJLIB : */
>    status = pj_init();
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>
>
>    /* Parse arguments */
>  local_port = (pj_uint16_t) LocalPort;
>    if (local_port < 1) {
>  printf("Error: invalid local port %s\n", pj_optarg);
>  return 1;
>    }
>
>
>  //USES_CONVERSION;
>  //std::string ipstr = std::string(W2A((wchar_t *) strRemoteIP));
>    //LPSTR ipstr = W2A((wchar_t *) strRemoteIP);
>  //const char ttt[] ="127.0.0.1";
>  //ipstr = "127.0.0.1";
>  //char *ttt = W2A((wchar_t *) strRemoteIP);
>
>
>  pj_str_t ip = pj_str(strRemoteIP);
>  pj_uint16_t port = (pj_uint16_t) RemotePort;
>
>  status = pj_sockaddr_in_init(&remote_addr, &ip, port);
>  if (status != PJ_SUCCESS) {
>      app_perror(THIS_FILE, "Invalid remote address", status);
>      return 2;
>  }
>  dir = PJMEDIA_DIR_ENCODING_DECODING;
>
>
>
>    /* Must create a pool factory before we can allocate any memory. */
>    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
>
>    /*
>     * Initialize media endpoint.
>     * This will implicitly initialize PJMEDIA too.
>     */
>    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>
>    /* Create memory pool for application purpose */
>    pool = pj_pool_create( &cp.factory,     /* pool factory     */
>      "app",     /* pool name.     */
>      4000,     /* init size     */
>      4000,     /* increment size     */
>      NULL      /* callback on error    */
>      );
>
>
>    /* Register all supported codecs */
>    status = init_codecs(med_endpt);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>
>
>    /* Find which codec to use. */
>    //codec_id = pj_optarg;
>    if (codec_id) {
>  unsigned count = 1;
>  pj_str_t str_codec_id = pj_str(codec_id);
>  pjmedia_codec_mgr *codec_mgr = pjmedia_endpt_get_codec_mgr(med_endpt);
>  status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr,
>            &str_codec_id, &count,
>            &codec_info, NULL);
>  if (status != PJ_SUCCESS) {
>   printf("Error: unable to find codec %s\n", codec_id);
>   return 4;
>  }
>    } else {
>  /* Default to pcmu */
>  pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(med_endpt),
>       0, &codec_info);
>  if (status != PJ_SUCCESS) {
>   printf("Error: unable to find/use default codec");
>   return 41;
>  }
>    }
>
>    /* Create stream based on program arguments */
>    status = create_stream(pool, med_endpt, codec_info, dir, local_port,
>      &remote_addr, &stream);
>    if (status != PJ_SUCCESS) {
>     //goto on_exit;
>     return 5;
>  }
>
>
>    /* Get the port interface of the stream */
>    status = pjmedia_stream_get_port( stream, &stream_port);
>    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>
>
>
>  /* Create sound device port. */
>  status = pjmedia_snd_port_create(pool, -1, -1,
>     stream_port->info.clock_rate,
>     stream_port->info.channel_count,
>     stream_port->info.samples_per_frame,
>     stream_port->info.bits_per_sample,
>     0, &snd_port);
>
>
>  if (status != PJ_SUCCESS) {
>     app_perror(THIS_FILE, "Unable to create sound port", status);
>     //goto on_exit;
>  return 6;
>  }
>
>  /* Connect sound port to stream */
>  status = pjmedia_snd_port_connect( snd_port, stream_port );
>  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>
>    /* Start streaming */
>    pjmedia_stream_start(stream);
>
>
>    /* Done */
>  printf("Stream is active, send/recv, local port is %d, "
>        "sending to %s:%d\n",
>        local_port,
>        pj_inet_ntoa(remote_addr.sin_addr),
>        pj_ntohs(remote_addr.sin_port));
>
>
> return 0;
>
>    /* Start deinitialization: */
>    return (status == PJ_SUCCESS) ? 0 : 1;
> }
>
>
>
> extern "C" __declspec(dllexport) int __stdcall StopStream()
> {
>     /* Destroy sound device */
>    if (snd_port) {
>  pjmedia_snd_port_destroy( snd_port );
>  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
>    }
>
>    /* Destroy stream */
>    if (stream) {
>  pjmedia_transport *tp;
>
>  tp = pjmedia_stream_get_transport(stream);
>  pjmedia_stream_destroy(stream);
>  pjmedia_transport_udp_close(tp);
>    }
>
>  deinit_codecs();
>
>    /* Release application pool */
>    pj_pool_release( pool );
>
>    /* Destroy media endpoint. */
>    pjmedia_endpt_destroy( med_endpt );
>
>    /* Destroy pool factory */
>    pj_caching_pool_destroy( &cp );
>
>    /* Shutdown PJLIB */
>    pj_shutdown();
>
>
> pj_caching_pool *cp = NULL;
> pjmedia_endpt *med_endpt = NULL;
> pj_pool_t *pool = NULL;
> pjmedia_snd_port *snd_port = NULL;
> pjmedia_stream *stream = NULL;
> pjmedia_port *stream_port = NULL;
>
>
>    return (status == PJ_SUCCESS) ? 0 : 1;
> }
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20080925/59f930e7/attachment.html>


[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