PJ_DEF(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr) { if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_ON_FAIL(mgr != NULL, return); if (mgr->thread) { mgr->is_quitting = PJ_TRUE; pj_sem_post(mgr->sem); pj_thread_join(mgr->thread); } if (mgr->sem) { pj_sem_destroy(mgr->sem); mgr->sem = NULL; } if (mgr->mutex) { pj_mutex_destroy(mgr->mutex); mgr->mutex = NULL; } if (mgr->pool) pj_pool_release(mgr->pool); if (event_manager_instance == mgr) event_manager_instance = NULL; }
PJ_DEF(pj_status_t) pjmedia_event_publish( pjmedia_event_mgr *mgr, void *epub, pjmedia_event *event, pjmedia_event_publish_flag flag) { pj_status_t err = PJ_SUCCESS; PJ_ASSERT_RETURN(epub && event, PJ_EINVAL); if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_RETURN(mgr, PJ_EINVAL); event->epub = epub; pj_mutex_lock(mgr->mutex); if (flag & PJMEDIA_EVENT_PUBLISH_POST_EVENT) { if (event_queue_add_event(&mgr->ev_queue, event) == PJ_SUCCESS) pj_sem_post(mgr->sem); } else { /* For nested pjmedia_event_publish() calls, i.e. calling publish() * inside the subscriber's callback, the function will only add * the event to the event queue of the first publish() call. It * is the first publish() call that will be responsible to * distribute the events. */ if (mgr->pub_ev_queue) { event_queue_add_event(mgr->pub_ev_queue, event); } else { static event_queue ev_queue; pj_status_t status; ev_queue.head = ev_queue.tail = 0; ev_queue.is_full = PJ_FALSE; mgr->pub_ev_queue = &ev_queue; event_queue_add_event(mgr->pub_ev_queue, event); do { status = event_mgr_distribute_events(mgr, mgr->pub_ev_queue, &mgr->pub_next_sub, PJ_FALSE); if (status != PJ_SUCCESS && err == PJ_SUCCESS) err = status; } while(ev_queue.head != ev_queue.tail || ev_queue.is_full); mgr->pub_ev_queue = NULL; } } pj_mutex_unlock(mgr->mutex); return err; }
PJ_DEF(pj_status_t) pjmedia_event_subscribe( pjmedia_event_mgr *mgr, pjmedia_event_cb *cb, void *user_data, void *epub) { esub *sub; PJ_ASSERT_RETURN(cb, PJ_EINVAL); if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_RETURN(mgr, PJ_EINVAL); pj_mutex_lock(mgr->mutex); /* Check whether callback function with the same user data is already * subscribed to the publisher. This is to prevent the callback function * receiving the same event from the same publisher more than once. */ sub = mgr->esub_list.next; while (sub != &mgr->esub_list) { esub *next = sub->next; if (sub->cb == cb && sub->user_data == user_data && sub->epub == epub) { pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; } sub = next; } if (mgr->free_esub_list.next != &mgr->free_esub_list) { sub = mgr->free_esub_list.next; pj_list_erase(sub); } else sub = PJ_POOL_ZALLOC_T(mgr->pool, esub); sub->cb = cb; sub->user_data = user_data; sub->epub = epub; pj_list_push_back(&mgr->esub_list, sub); pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; }
pjmedia_event_unsubscribe(pjmedia_event_mgr *mgr, pjmedia_event_cb *cb, void *user_data, void *epub) { esub *sub; PJ_ASSERT_RETURN(cb, PJ_EINVAL); if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_RETURN(mgr, PJ_EINVAL); pj_mutex_lock(mgr->mutex); sub = mgr->esub_list.next; while (sub != &mgr->esub_list) { esub *next = sub->next; if (sub->cb == cb && (sub->user_data == user_data || !user_data) && (sub->epub == epub || !epub)) { /* If the worker thread or pjmedia_event_publish() API is * in the process of distributing events, make sure that * its pointer to the next subscriber stays valid. */ if (mgr->th_next_sub == sub) mgr->th_next_sub = sub->next; if (mgr->pub_next_sub == sub) mgr->pub_next_sub = sub->next; pj_list_erase(sub); pj_list_push_back(&mgr->free_esub_list, sub); if (user_data && epub) break; } sub = next; } pj_mutex_unlock(mgr->mutex); return PJ_SUCCESS; }
static int main_func(int argc, char *argv[]) { pj_caching_pool cp; pj_pool_t *pool; int rc = 0; pj_status_t status = PJ_SUCCESS; if (argc != 2) { puts("Error: filename required"); puts(desc); return 1; } /* Must init PJLIB first: */ status = pj_init(); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Must create a pool factory before we can allocate any memory. */ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); /* Create memory pool for our file player */ pool = pj_pool_create( &cp.factory, /* pool factory */ "AVI", /* pool name. */ 4000, /* init size */ 4000, /* increment size */ NULL /* callback on error */ ); pjmedia_video_format_mgr_create(pool, 64, 0, NULL); pjmedia_converter_mgr_create(pool, NULL); pjmedia_event_mgr_create(pool, 0, NULL); pjmedia_vid_codec_mgr_create(pool, NULL); status = pjmedia_vid_dev_subsys_init(&cp.factory); if (status != PJ_SUCCESS) goto on_return; status = pjmedia_aud_subsys_init(&cp.factory); if (status != PJ_SUCCESS) { goto on_return; } #if PJMEDIA_HAS_FFMPEG_VID_CODEC status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory); if (status != PJ_SUCCESS) goto on_return; #endif rc = aviplay(pool, argv[1]); /* * File should be playing and looping now */ /* Without this sleep, Windows/DirectSound will repeteadly * play the last frame during destroy. */ pj_thread_sleep(100); on_return: #if PJMEDIA_HAS_FFMPEG_VID_CODEC pjmedia_codec_ffmpeg_vid_deinit(); #endif pjmedia_aud_subsys_shutdown(); pjmedia_vid_dev_subsys_shutdown(); pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance()); pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance()); pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance()); /* Release application pool */ pj_pool_release( pool ); /* Destroy pool factory */ pj_caching_pool_destroy( &cp ); /* Shutdown PJLIB */ pj_shutdown(); /* Done. */ return 0; }
int test_main(void) { int rc = 0; pj_caching_pool caching_pool; pj_pool_t *pool; pj_init(); pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0); pool = pj_pool_create(&caching_pool.factory, "test", 1000, 512, NULL); pj_log_set_decor(PJ_LOG_HAS_NEWLINE); pj_log_set_level(3); mem = &caching_pool.factory; #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) pjmedia_video_format_mgr_create(pool, 64, 0, NULL); pjmedia_converter_mgr_create(pool, NULL); pjmedia_event_mgr_create(pool, 0, NULL); pjmedia_vid_codec_mgr_create(pool, NULL); #endif #if HAS_VID_PORT_TEST DO_TEST(vid_port_test()); #endif #if HAS_VID_DEV_TEST DO_TEST(vid_dev_test()); #endif #if HAS_VID_CODEC_TEST DO_TEST(vid_codec_test()); #endif #if HAS_SDP_NEG_TEST DO_TEST(sdp_neg_test()); #endif //DO_TEST(sdp_test (&caching_pool.factory)); //DO_TEST(rtp_test(&caching_pool.factory)); //DO_TEST(session_test (&caching_pool.factory)); #if HAS_JBUF_TEST DO_TEST(jbuf_main()); #endif #if HAS_MIPS_TEST DO_TEST(mips_test()); #endif #if HAS_CODEC_VECTOR_TEST DO_TEST(codec_test_vectors()); #endif PJ_LOG(3,(THIS_FILE," ")); on_return: if (rc != 0) { PJ_LOG(3,(THIS_FILE,"Test completed with error(s)!")); } else { PJ_LOG(3,(THIS_FILE,"Looks like everything is okay!")); } #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance()); pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance()); pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance()); #endif pj_pool_release(pool); pj_caching_pool_destroy(&caching_pool); return rc; }