Compare commits
8 Commits
master
...
support-2.
Author | SHA1 | Date |
---|---|---|
sauwming | bb2287b3a8 | |
Riza Sulistyo | 806b7c2f7e | |
Matthew Fredrickson | bbf7f229de | |
sauwming | 6d72311fc8 | |
sauwming | 4cea72a4db | |
Nanang Izzuddin | 563f34c097 | |
Nanang Izzuddin | 24006a72c9 | |
sauwming | f1e6313389 |
|
@ -127,6 +127,9 @@ static pj_status_t get_name_len(int rec_counter, const pj_uint8_t *pkt,
|
|||
return PJLIB_UTIL_EDNSINNAMEPTR;
|
||||
}
|
||||
|
||||
if (start >= max)
|
||||
return PJLIB_UTIL_EDNSINNAMEPTR;
|
||||
|
||||
*name_len = *parsed_len = 0;
|
||||
p = start;
|
||||
while (*p) {
|
||||
|
@ -199,6 +202,9 @@ static pj_status_t get_name(int rec_counter, const pj_uint8_t *pkt,
|
|||
return PJLIB_UTIL_EDNSINNAMEPTR;
|
||||
}
|
||||
|
||||
if (start >= max)
|
||||
return PJLIB_UTIL_EDNSINNAMEPTR;
|
||||
|
||||
p = start;
|
||||
while (*p) {
|
||||
if ((*p & 0xc0) == 0xc0) {
|
||||
|
@ -359,10 +365,14 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
|
|||
|
||||
/* Parse some well known records */
|
||||
if (rr->type == PJ_DNS_TYPE_A) {
|
||||
if (p + 4 > max)
|
||||
return PJLIB_UTIL_EDNSINSIZE;
|
||||
pj_memcpy(&rr->rdata.a.ip_addr, p, 4);
|
||||
p += 4;
|
||||
|
||||
} else if (rr->type == PJ_DNS_TYPE_AAAA) {
|
||||
if (p + 16 > max)
|
||||
return PJLIB_UTIL_EDNSINSIZE;
|
||||
pj_memcpy(&rr->rdata.aaaa.ip_addr, p, 16);
|
||||
p += 16;
|
||||
|
||||
|
@ -388,6 +398,8 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
|
|||
p += name_part_len;
|
||||
|
||||
} else if (rr->type == PJ_DNS_TYPE_SRV) {
|
||||
if (p + 6 > max)
|
||||
return PJLIB_UTIL_EDNSINSIZE;
|
||||
|
||||
/* Priority */
|
||||
pj_memcpy(&rr->rdata.srv.prio, p, 2);
|
||||
|
|
|
@ -1409,7 +1409,7 @@ PJ_BEGIN_DECL
|
|||
#define PJ_VERSION_NUM_MINOR 13
|
||||
|
||||
/** PJLIB version revision number. */
|
||||
#define PJ_VERSION_NUM_REV 0
|
||||
#define PJ_VERSION_NUM_REV 1
|
||||
|
||||
/**
|
||||
* Extra suffix for the version (e.g. "-trunk"), or empty for
|
||||
|
|
|
@ -244,6 +244,7 @@ static void ssl_close_sockets(pj_ssl_sock_t *ssock)
|
|||
static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
|
||||
pj_status_t status)
|
||||
{
|
||||
ssock->handshake_status = status;
|
||||
/* Cancel handshake timer */
|
||||
if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) {
|
||||
pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer);
|
||||
|
|
|
@ -112,6 +112,7 @@ struct pj_ssl_sock_t
|
|||
pj_ioqueue_op_key_t shutdown_op_key;
|
||||
pj_timer_entry timer;
|
||||
pj_status_t verify_status;
|
||||
pj_status_t handshake_status;
|
||||
|
||||
pj_bool_t is_closing;
|
||||
unsigned long last_err;
|
||||
|
|
|
@ -1695,8 +1695,16 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
|
|||
/* Reset SSL socket state */
|
||||
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
|
||||
{
|
||||
int post_unlock_flush_circ_buf = 0;
|
||||
|
||||
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
|
||||
|
||||
/* Must lock around SSL calls, particularly SSL_shutdown
|
||||
* as it can modify the write BIOs and destructively
|
||||
* interfere with any ssl_write() calls in progress
|
||||
* above in a multithreaded environment */
|
||||
pj_lock_acquire(ssock->write_mutex);
|
||||
|
||||
/* Detach from SSL instance */
|
||||
if (ossock->ossl_ssl) {
|
||||
SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
|
||||
|
@ -1706,19 +1714,32 @@ static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
|
|||
* Avoid calling SSL_shutdown() if handshake wasn't completed.
|
||||
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during an
|
||||
* SSL handshake, while previous versions always return 0.
|
||||
* Call SSL_shutdown() when there is a timeout handshake failure or
|
||||
* the last error is not SSL_ERROR_SYSCALL and not SSL_ERROR_SSL.
|
||||
*/
|
||||
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
|
||||
int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
if (ret == 0) {
|
||||
/* Flush data to send close notify. */
|
||||
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
|
||||
if (ssock->handshake_status == PJ_ETIMEDOUT ||
|
||||
(ssock->last_err != SSL_ERROR_SYSCALL &&
|
||||
ssock->last_err != SSL_ERROR_SSL))
|
||||
{
|
||||
int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
if (ret == 0) {
|
||||
/* SSL_shutdown will potentially trigger a bunch of
|
||||
* data to dump to the socket */
|
||||
post_unlock_flush_circ_buf = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pj_lock_acquire(ssock->write_mutex);
|
||||
ssock->ssl_state = SSL_STATE_NULL;
|
||||
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
|
||||
if (post_unlock_flush_circ_buf) {
|
||||
/* Flush data to send close notify. */
|
||||
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
|
||||
}
|
||||
|
||||
ssl_close_sockets(ssock);
|
||||
|
||||
/* Upon error, OpenSSL may leave any error description in the thread
|
||||
|
@ -2413,7 +2434,6 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
|
|||
*/
|
||||
pj_lock_acquire(ssock->write_mutex);
|
||||
*size = size_ = SSL_read(ossock->ossl_ssl, data, size_);
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
|
||||
if (size_ <= 0) {
|
||||
pj_status_t status;
|
||||
|
@ -2436,15 +2456,22 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
|
|||
/* Reset SSL socket state, then return PJ_FALSE */
|
||||
status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
|
||||
err, len);
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
/* Unfortunately we can't hold the lock here to reset all the state.
|
||||
* We probably should though.
|
||||
*/
|
||||
ssl_reset_sock_state(ssock);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
/* Need renegotiation */
|
||||
return PJ_EEOF;
|
||||
}
|
||||
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,8 @@
|
|||
|
||||
#define THIS_FILE "darwin_dev.m"
|
||||
#define DEFAULT_CLOCK_RATE 90000
|
||||
#if TARGET_OS_IPHONE
|
||||
#define DEFAULT_WIDTH 352
|
||||
#define DEFAULT_HEIGHT 288
|
||||
#else
|
||||
#define DEFAULT_WIDTH 1280
|
||||
#define DEFAULT_HEIGHT 720
|
||||
#endif
|
||||
#define DEFAULT_WIDTH 640
|
||||
#define DEFAULT_HEIGHT 480
|
||||
#define DEFAULT_FPS 15
|
||||
|
||||
/* Define whether we should maintain the aspect ratio when rotating the image.
|
||||
|
@ -144,7 +139,6 @@ struct darwin_stream
|
|||
AVCaptureVideoDataOutput *video_output;
|
||||
VOutDelegate *vout_delegate;
|
||||
dispatch_queue_t queue;
|
||||
AVCaptureVideoPreviewLayer *prev_layer;
|
||||
|
||||
pj_bool_t is_running;
|
||||
#if TARGET_OS_IPHONE
|
||||
|
@ -153,6 +147,8 @@ struct darwin_stream
|
|||
pj_size_t render_buf_size;
|
||||
CGDataProviderRef render_data_provider;
|
||||
UIView *render_view;
|
||||
AVCaptureVideoPreviewLayer *prev_layer;
|
||||
UIView *prev_view;
|
||||
#endif
|
||||
|
||||
pj_timestamp frame_ts;
|
||||
|
@ -236,6 +232,7 @@ static void set_preset_str()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
static void dispatch_sync_on_main_queue(void (^block)(void))
|
||||
{
|
||||
if ([NSThread isMainThread]) {
|
||||
|
@ -244,6 +241,7 @@ static void dispatch_sync_on_main_queue(void (^block)(void))
|
|||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Factory operations
|
||||
|
@ -1018,11 +1016,18 @@ static pj_status_t darwin_stream_get_cap(pjmedia_vid_dev_stream *s,
|
|||
|
||||
switch (cap) {
|
||||
#if TARGET_OS_IPHONE
|
||||
case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
|
||||
{
|
||||
pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd *) pval;
|
||||
hwnd->type = PJMEDIA_VID_DEV_HWND_TYPE_IOS;
|
||||
hwnd->info.ios.window = (void *)strm->prev_view;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
|
||||
{
|
||||
pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd*) pval;
|
||||
hwnd->type = PJMEDIA_VID_DEV_HWND_TYPE_NONE;
|
||||
hwnd->info.ios.window = (void*)strm->render_view;
|
||||
pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd *) pval;
|
||||
hwnd->type = PJMEDIA_VID_DEV_HWND_TYPE_IOS;
|
||||
hwnd->info.ios.window = (void *)strm->render_view;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
#endif /* TARGET_OS_IPHONE */
|
||||
|
@ -1043,6 +1048,7 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
|
||||
|
||||
switch (cap) {
|
||||
#if TARGET_OS_IPHONE
|
||||
/* Native preview */
|
||||
case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
|
||||
{
|
||||
|
@ -1053,7 +1059,8 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
if (strm->prev_layer) {
|
||||
CALayer *prev_layer = strm->prev_layer;
|
||||
dispatch_sync_on_main_queue(^{
|
||||
[prev_layer removeFromSuperlayer];
|
||||
if ([prev_layer superlayer])
|
||||
[prev_layer removeFromSuperlayer];
|
||||
[prev_layer release];
|
||||
});
|
||||
strm->prev_layer = nil;
|
||||
|
@ -1072,29 +1079,34 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
if (!strm->cap_session)
|
||||
return PJ_EINVALIDOP;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
/* Preview layer instantiation should be in main thread! */
|
||||
dispatch_sync_on_main_queue(^{
|
||||
/* Create view, if none */
|
||||
if (!strm->render_view)
|
||||
darwin_init_view(strm);
|
||||
|
||||
/* Create preview layer */
|
||||
AVCaptureVideoPreviewLayer *prev_layer =
|
||||
[[AVCaptureVideoPreviewLayer alloc]
|
||||
initWithSession:strm->cap_session];
|
||||
|
||||
/* Attach preview layer to a UIView */
|
||||
prev_layer.videoGravity = AVLayerVideoGravityResize;
|
||||
prev_layer.frame = strm->render_view.bounds;
|
||||
[strm->render_view.layer addSublayer:prev_layer];
|
||||
strm->prev_layer = prev_layer;
|
||||
strm->prev_layer = [[AVCaptureVideoPreviewLayer alloc]
|
||||
initWithSession:strm->cap_session];
|
||||
strm->prev_layer.videoGravity =
|
||||
AVLayerVideoGravityResizeAspectFill;
|
||||
|
||||
/* Create preview view and init it at smaller size than
|
||||
* the actual video.
|
||||
*/
|
||||
if (!strm->prev_view) {
|
||||
CGRect rect;
|
||||
rect = CGRectMake(0, 0, strm->param.fmt.det.vid.size.w/2,
|
||||
strm->param.fmt.det.vid.size.h/2);
|
||||
strm->prev_view = [[UIView alloc] initWithFrame:rect];
|
||||
}
|
||||
|
||||
/* Add the preview layer as sublayer */
|
||||
strm->prev_layer.frame = strm->prev_view.bounds;
|
||||
[strm->prev_view.layer addSublayer:strm->prev_layer];
|
||||
|
||||
});
|
||||
PJ_LOG(4, (THIS_FILE, "Native preview initialized"));
|
||||
#endif
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fast switch */
|
||||
case PJMEDIA_VID_DEV_CAP_SWITCH:
|
||||
|
@ -1198,8 +1210,6 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
r.size = CGSizeMake(strm->param.disp_size.w,
|
||||
strm->param.disp_size.h);
|
||||
strm->render_view.bounds = r;
|
||||
if (strm->prev_layer)
|
||||
strm->prev_layer.frame = r;
|
||||
});
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -1450,6 +1460,15 @@ static pj_status_t darwin_stream_destroy(pjmedia_vid_dev_stream *strm)
|
|||
[stream->render_view release];
|
||||
stream->render_view = nil;
|
||||
}
|
||||
|
||||
if (stream->prev_view) {
|
||||
[stream->prev_view
|
||||
performSelectorOnMainThread:@selector(removeFromSuperview)
|
||||
withObject:nil waitUntilDone:YES];
|
||||
|
||||
[stream->prev_view release];
|
||||
stream->prev_view = nil;
|
||||
}
|
||||
|
||||
if (stream->render_data_provider) {
|
||||
CGDataProviderRelease(stream->render_data_provider);
|
||||
|
|
|
@ -255,6 +255,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
/* Create own pool */
|
||||
pool = pj_pool_create(parent_pool->factory, "vidconf", 500, 500, NULL);
|
||||
if (!pool) {
|
||||
PJ_PERROR(1, (THIS_FILE, PJ_ENOMEM, "Create failed in alloc"));
|
||||
return PJ_ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -275,6 +276,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
pj_pool_zalloc(pool, vid_conf->opt.max_slot_cnt *
|
||||
sizeof(vconf_port*));
|
||||
if (!vid_conf->ports) {
|
||||
PJ_PERROR(1, (THIS_FILE, PJ_ENOMEM, "Create failed in alloc ports"));
|
||||
pjmedia_vid_conf_destroy(vid_conf);
|
||||
return PJ_ENOMEM;
|
||||
}
|
||||
|
@ -282,6 +284,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
/* Create mutex */
|
||||
status = pj_mutex_create_recursive(pool, CONF_NAME, &vid_conf->mutex);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(1, (THIS_FILE, status, "Create failed in create mutex"));
|
||||
pjmedia_vid_conf_destroy(vid_conf);
|
||||
return status;
|
||||
}
|
||||
|
@ -293,6 +296,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
status = pjmedia_clock_create2(pool, &clock_param, 0, &on_clock_tick,
|
||||
vid_conf, &vid_conf->clock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(1, (THIS_FILE, status, "Create failed in create clock"));
|
||||
pjmedia_vid_conf_destroy(vid_conf);
|
||||
return status;
|
||||
}
|
||||
|
@ -301,6 +305,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
vid_conf->op_queue = PJ_POOL_ZALLOC_T(pool, op_entry);
|
||||
vid_conf->op_queue_free = PJ_POOL_ZALLOC_T(pool, op_entry);
|
||||
if (!vid_conf->op_queue || !vid_conf->op_queue_free) {
|
||||
PJ_PERROR(1, (THIS_FILE, PJ_ENOMEM, "Create failed in create queues"));
|
||||
pjmedia_vid_conf_destroy(vid_conf);
|
||||
return PJ_ENOMEM;
|
||||
}
|
||||
|
@ -310,7 +315,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_create(
|
|||
/* Done */
|
||||
*p_vid_conf = vid_conf;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Created video conference bridge with %d ports",
|
||||
PJ_LOG(4,(THIS_FILE, "Created video conference bridge with %d ports",
|
||||
vid_conf->opt.max_slot_cnt));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
@ -354,7 +359,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_destroy(pjmedia_vid_conf *vid_conf)
|
|||
pj_pool_safe_release(&vid_conf->pool);
|
||||
}
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Video conference bridge destroyed"));
|
||||
PJ_LOG(4,(THIS_FILE, "Video conference bridge destroyed"));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -375,6 +380,8 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
unsigned index;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Add port %s requested", port->info.name.ptr));
|
||||
|
||||
PJ_ASSERT_RETURN(vid_conf && parent_pool && port, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(port->info.fmt.type==PJMEDIA_TYPE_VIDEO &&
|
||||
port->info.fmt.detail_type==PJMEDIA_FORMAT_DETAIL_VIDEO,
|
||||
|
@ -388,6 +395,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
pj_mutex_lock(vid_conf->mutex);
|
||||
|
||||
if (vid_conf->port_cnt >= vid_conf->opt.max_slot_cnt) {
|
||||
PJ_PERROR(3,(THIS_FILE, PJ_ETOOMANY, "Add port %s failed", name->ptr));
|
||||
pj_assert(!"Too many ports");
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return PJ_ETOOMANY;
|
||||
|
@ -457,7 +465,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
|
||||
vfi = pjmedia_get_video_format_info(NULL, port->info.fmt.id);
|
||||
if (!vfi) {
|
||||
PJ_LOG(4,(THIS_FILE, "pjmedia_vid_conf_add_port(): "
|
||||
PJ_LOG(3,(THIS_FILE, "pjmedia_vid_conf_add_port(): "
|
||||
"unrecognized format %04X",
|
||||
port->info.fmt.id));
|
||||
status = PJMEDIA_EBADFMT;
|
||||
|
@ -468,7 +476,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
vafp.size = port->info.fmt.det.vid.size;
|
||||
status = (*vfi->apply_fmt)(vfi, &vafp);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(4,(THIS_FILE, "pjmedia_vid_conf_add_port(): "
|
||||
PJ_LOG(3,(THIS_FILE, "pjmedia_vid_conf_add_port(): "
|
||||
"Failed to apply format %04X",
|
||||
port->info.fmt.id));
|
||||
goto on_error;
|
||||
|
@ -482,7 +490,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
cport->put_buf,
|
||||
cport->put_buf_size);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4,(THIS_FILE, status,
|
||||
PJ_PERROR(3,(THIS_FILE, status,
|
||||
"Warning: failed to init sink buffer "
|
||||
" with black"));
|
||||
}
|
||||
|
@ -496,7 +504,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_add_port( pjmedia_vid_conf *vid_conf,
|
|||
cport->get_buf,
|
||||
cport->get_buf_size);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4,(THIS_FILE, status,
|
||||
PJ_PERROR(3,(THIS_FILE, status,
|
||||
"Warning: failed to init source buffer "
|
||||
"with black"));
|
||||
}
|
||||
|
@ -564,6 +572,8 @@ on_error:
|
|||
if (pool)
|
||||
pj_pool_release(pool);
|
||||
|
||||
PJ_PERROR(3, (THIS_FILE, status, "Add port %s failed", name->ptr));
|
||||
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return status;
|
||||
}
|
||||
|
@ -578,6 +588,8 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_remove_port( pjmedia_vid_conf *vid_conf,
|
|||
vconf_port *cport;
|
||||
op_entry *ope;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Port %d remove requested", slot));
|
||||
|
||||
PJ_ASSERT_RETURN(vid_conf && slot<vid_conf->opt.max_slot_cnt, PJ_EINVAL);
|
||||
|
||||
pj_mutex_lock(vid_conf->mutex);
|
||||
|
@ -585,11 +597,12 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_remove_port( pjmedia_vid_conf *vid_conf,
|
|||
/* Port must be valid. */
|
||||
cport = vid_conf->ports[slot];
|
||||
if (cport == NULL) {
|
||||
PJ_PERROR(3, (THIS_FILE, PJ_EINVAL, "Remove port failed"));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return PJ_EINVAL;
|
||||
}
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Video port %d remove requested", slot));
|
||||
PJ_LOG(4,(THIS_FILE, "Video port %d remove queued", slot));
|
||||
|
||||
/* Queue the operation */
|
||||
ope = get_free_op_entry(vid_conf);
|
||||
|
@ -646,7 +659,7 @@ static void op_remove_port(pjmedia_vid_conf *vid_conf,
|
|||
/* Warning: will stuck if this is called from the clock thread */
|
||||
status = pjmedia_clock_stop(vid_conf->clock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4, (THIS_FILE, status, "Failed to stop clock"));
|
||||
PJ_PERROR(3, (THIS_FILE, status, "Failed to stop clock"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -741,6 +754,9 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_connect_port(
|
|||
vconf_port *src_port, *dst_port;
|
||||
unsigned i;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Connect ports %d->%d requested",
|
||||
src_slot, sink_slot));
|
||||
|
||||
/* Check arguments */
|
||||
PJ_ASSERT_RETURN(vid_conf &&
|
||||
src_slot<vid_conf->opt.max_slot_cnt &&
|
||||
|
@ -755,7 +771,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_connect_port(
|
|||
if (!src_port || !src_port->port->get_frame ||
|
||||
!dst_port || !dst_port->port->put_frame)
|
||||
{
|
||||
PJ_LOG(4,(THIS_FILE,"Failed connecting video ports, make sure that "
|
||||
PJ_LOG(3,(THIS_FILE,"Failed connecting video ports, make sure that "
|
||||
"source has get_frame() & sink has put_frame()"));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return PJ_EINVAL;
|
||||
|
@ -771,7 +787,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_connect_port(
|
|||
if (i == src_port->listener_cnt) {
|
||||
op_entry *ope;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Video connect ports %d->%d requested",
|
||||
PJ_LOG(4,(THIS_FILE, "Video connect ports %d->%d queued",
|
||||
src_slot, sink_slot));
|
||||
|
||||
ope = get_free_op_entry(vid_conf);
|
||||
|
@ -786,7 +802,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_connect_port(
|
|||
pj_status_t status;
|
||||
status = pjmedia_clock_start(vid_conf->clock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4, (THIS_FILE, status, "Failed to start clock"));
|
||||
PJ_PERROR(2, (THIS_FILE, status, "Failed to start clock"));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return status;
|
||||
}
|
||||
|
@ -848,6 +864,9 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_disconnect_port(
|
|||
vconf_port *src_port, *dst_port;
|
||||
unsigned i, j;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Disconnect ports %d->%d requested",
|
||||
src_slot, sink_slot));
|
||||
|
||||
/* Check arguments */
|
||||
PJ_ASSERT_RETURN(vid_conf &&
|
||||
src_slot<vid_conf->opt.max_slot_cnt &&
|
||||
|
@ -859,6 +878,9 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_disconnect_port(
|
|||
src_port = vid_conf->ports[src_slot];
|
||||
dst_port = vid_conf->ports[sink_slot];
|
||||
if (!src_port || !dst_port) {
|
||||
PJ_PERROR(3,(THIS_FILE, PJ_EINVAL,
|
||||
"Disconnect ports failed, src=0x%p dst=0x%p",
|
||||
src_port, dst_port));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return PJ_EINVAL;
|
||||
}
|
||||
|
@ -874,24 +896,26 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_disconnect_port(
|
|||
}
|
||||
|
||||
if (i != src_port->listener_cnt && j != dst_port->transmitter_cnt) {
|
||||
op_entry *ope;
|
||||
|
||||
pj_assert(src_port->listener_cnt > 0 &&
|
||||
src_port->listener_cnt < vid_conf->opt.max_slot_cnt);
|
||||
pj_assert(dst_port->transmitter_cnt > 0 &&
|
||||
dst_port->transmitter_cnt < vid_conf->opt.max_slot_cnt);
|
||||
|
||||
/* Queue the operation */
|
||||
if (i == src_port->listener_cnt) {
|
||||
op_entry *ope;
|
||||
PJ_LOG(4,(THIS_FILE, "Video disconnect ports %d->%d queued",
|
||||
src_slot, sink_slot));
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Video disconnect ports %d->%d requested",
|
||||
src_slot, sink_slot));
|
||||
|
||||
ope = get_free_op_entry(vid_conf);
|
||||
ope->type = OP_DISCONNECT_PORTS;
|
||||
ope->param.disconnect_ports.src = src_slot;
|
||||
ope->param.disconnect_ports.sink = sink_slot;
|
||||
pj_list_push_back(vid_conf->op_queue, ope);
|
||||
}
|
||||
ope = get_free_op_entry(vid_conf);
|
||||
ope->type = OP_DISCONNECT_PORTS;
|
||||
ope->param.disconnect_ports.src = src_slot;
|
||||
ope->param.disconnect_ports.sink = sink_slot;
|
||||
pj_list_push_back(vid_conf->op_queue, ope);
|
||||
} else {
|
||||
PJ_PERROR(3,(THIS_FILE, PJ_EINVAL,
|
||||
"Disconnect ports failed, src=0x%p dst=0x%p",
|
||||
src_port, dst_port));
|
||||
}
|
||||
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
|
@ -1467,6 +1491,8 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_update_port( pjmedia_vid_conf *vid_conf,
|
|||
vconf_port *cport;
|
||||
op_entry *ope;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Update port %d requested", slot));
|
||||
|
||||
PJ_ASSERT_RETURN(vid_conf && slot<vid_conf->opt.max_slot_cnt, PJ_EINVAL);
|
||||
|
||||
pj_mutex_lock(vid_conf->mutex);
|
||||
|
@ -1474,6 +1500,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_update_port( pjmedia_vid_conf *vid_conf,
|
|||
/* Port must be valid. */
|
||||
cport = vid_conf->ports[slot];
|
||||
if (cport == NULL) {
|
||||
PJ_PERROR(3,(THIS_FILE, PJ_EINVAL, "Update port failed"));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
return PJ_EINVAL;
|
||||
}
|
||||
|
@ -1484,6 +1511,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_conf_update_port( pjmedia_vid_conf *vid_conf,
|
|||
ope->param.update_port.port = slot;
|
||||
pj_list_push_back(vid_conf->op_queue, ope);
|
||||
|
||||
PJ_LOG(4,(THIS_FILE, "Update port %d queued", slot));
|
||||
pj_mutex_unlock(vid_conf->mutex);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
@ -1602,6 +1630,7 @@ static void op_update_port(pjmedia_vid_conf *vid_conf,
|
|||
|
||||
/* Update cport format info */
|
||||
cport->format = *new_fmt;
|
||||
PJ_LOG(4,(THIS_FILE, "Port %d updated", slot));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -442,6 +442,7 @@ typedef enum pj_stun_status
|
|||
|
||||
\endverbatim
|
||||
*/
|
||||
#pragma pack(1)
|
||||
typedef struct pj_stun_msg_hdr
|
||||
{
|
||||
/**
|
||||
|
@ -473,6 +474,7 @@ typedef struct pj_stun_msg_hdr
|
|||
pj_uint8_t tsx_id[12];
|
||||
|
||||
} pj_stun_msg_hdr;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/**
|
||||
|
@ -490,6 +492,7 @@ typedef struct pj_stun_msg_hdr
|
|||
|
||||
\endverbatim
|
||||
*/
|
||||
#pragma pack(1)
|
||||
typedef struct pj_stun_attr_hdr
|
||||
{
|
||||
/**
|
||||
|
@ -506,6 +509,7 @@ typedef struct pj_stun_attr_hdr
|
|||
pj_uint16_t length;
|
||||
|
||||
} pj_stun_attr_hdr;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -746,7 +746,7 @@ PJ_DEF(int) pj_stun_set_padding_char(int chr)
|
|||
|
||||
#define INIT_ATTR(a,t,l) (a)->hdr.type=(pj_uint16_t)(t), \
|
||||
(a)->hdr.length=(pj_uint16_t)(l)
|
||||
#define ATTR_HDR_LEN 4
|
||||
#define ATTR_HDR_LEN sizeof(pj_stun_attr_hdr)
|
||||
|
||||
static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos)
|
||||
{
|
||||
|
@ -1438,12 +1438,12 @@ static pj_status_t decode_uint_attr(pj_pool_t *pool,
|
|||
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr);
|
||||
GETATTRHDR(buf, &attr->hdr);
|
||||
|
||||
attr->value = GETVAL32H(buf, 4);
|
||||
|
||||
/* Check that the attribute length is valid */
|
||||
if (attr->hdr.length != 4)
|
||||
return PJNATH_ESTUNINATTRLEN;
|
||||
|
||||
attr->value = GETVAL32H(buf, 4);
|
||||
|
||||
/* Done */
|
||||
*p_attr = attr;
|
||||
|
||||
|
@ -1757,14 +1757,15 @@ static pj_status_t decode_errcode_attr(pj_pool_t *pool,
|
|||
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr);
|
||||
GETATTRHDR(buf, &attr->hdr);
|
||||
|
||||
/* Check that the attribute length is valid */
|
||||
if (attr->hdr.length < 4)
|
||||
return PJNATH_ESTUNINATTRLEN;
|
||||
|
||||
attr->err_code = buf[6] * 100 + buf[7];
|
||||
|
||||
/* Get pointer to the string in the message */
|
||||
value.ptr = ((char*)buf + ATTR_HDR_LEN + 4);
|
||||
value.slen = attr->hdr.length - 4;
|
||||
/* Make sure the length is never negative */
|
||||
if (value.slen < 0)
|
||||
value.slen = 0;
|
||||
|
||||
/* Copy the string to the attribute */
|
||||
pj_strdup(pool, &attr->reason, &value);
|
||||
|
@ -2327,6 +2328,14 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
|
|||
status = pj_stun_msg_check(pdu, pdu_len, options);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
} else {
|
||||
/* For safety, verify packet length at least */
|
||||
pj_uint32_t msg_len = GETVAL16H(pdu, 2) + 20;
|
||||
if (msg_len > pdu_len ||
|
||||
((options & PJ_STUN_IS_DATAGRAM) && msg_len != pdu_len))
|
||||
{
|
||||
return PJNATH_EINSTUNMSGLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the message, copy the header, and convert to host byte order */
|
||||
|
@ -2345,7 +2354,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
|
|||
p_response = NULL;
|
||||
|
||||
/* Parse attributes */
|
||||
while (pdu_len >= 4) {
|
||||
while (pdu_len >= ATTR_HDR_LEN) {
|
||||
unsigned attr_type, attr_val_len;
|
||||
const struct attr_desc *adesc;
|
||||
|
||||
|
@ -2357,7 +2366,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
|
|||
attr_val_len = (attr_val_len + 3) & (~3);
|
||||
|
||||
/* Check length */
|
||||
if (pdu_len < attr_val_len) {
|
||||
if (pdu_len < attr_val_len + ATTR_HDR_LEN) {
|
||||
pj_str_t err_msg;
|
||||
char err_msg_buf[80];
|
||||
|
||||
|
|
|
@ -354,37 +354,30 @@ void displayWindow(pjsua_vid_win_id wid)
|
|||
for (;i < last; ++i) {
|
||||
pjsua_vid_win_info wi;
|
||||
|
||||
if (pjsua_vid_win_get_info(i, &wi) == PJ_SUCCESS) {
|
||||
if (pjsua_vid_win_get_info(i, &wi) == PJ_SUCCESS &&
|
||||
wi.hwnd.info.ios.window)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIView *parent = app.viewController.view;
|
||||
UIView *view = (__bridge UIView *)wi.hwnd.info.ios.window;
|
||||
|
||||
if (view) {
|
||||
/* Add the video window as subview */
|
||||
if (![view isDescendantOfView:parent])
|
||||
[parent addSubview:view];
|
||||
|
||||
if (!wi.is_native) {
|
||||
/* Resize it to fit width */
|
||||
view.bounds = CGRectMake(0, 0, parent.bounds.size.width,
|
||||
(parent.bounds.size.height *
|
||||
1.0*parent.bounds.size.width/
|
||||
view.bounds.size.width));
|
||||
/* Center it horizontally */
|
||||
view.center = CGPointMake(parent.bounds.size.width/2.0,
|
||||
view.bounds.size.height/2.0);
|
||||
} else {
|
||||
/* Preview window, move it to the bottom */
|
||||
view.center = CGPointMake(parent.bounds.size.width/2.0,
|
||||
parent.bounds.size.height-
|
||||
view.bounds.size.height/2.0);
|
||||
}
|
||||
|
||||
if (![view isDescendantOfView:parent])
|
||||
[parent addSubview:view];
|
||||
|
||||
if (!wi.is_native) {
|
||||
/* Video window */
|
||||
view.contentMode = UIViewContentModeScaleAspectFit;
|
||||
view.center = parent.center;
|
||||
view.frame = parent.bounds;
|
||||
} else {
|
||||
/* Preview window */
|
||||
view.contentMode = UIViewContentModeBottomLeft;
|
||||
view.frame = CGRectMake(0, parent.frame.size.height - view.frame.size.height,
|
||||
view.frame.size.width, view.frame.size.height);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -705,11 +705,14 @@ static pj_status_t create_vid_win(pjsua_vid_win_type type,
|
|||
}
|
||||
}
|
||||
|
||||
status = pjsua_vid_conf_connect(w->cap_slot, w->rend_slot, NULL);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4, (THIS_FILE, status,
|
||||
"Ignored error on connecting video ports "
|
||||
"on wid=%d", wid));
|
||||
if (!w->is_native) {
|
||||
status = pjsua_vid_conf_connect(w->cap_slot, w->rend_slot,
|
||||
NULL);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(4, (THIS_FILE, status,
|
||||
"Ignored error on connecting video ports "
|
||||
"on wid=%d", wid));
|
||||
}
|
||||
}
|
||||
|
||||
/* Done */
|
||||
|
@ -1700,7 +1703,7 @@ PJ_DEF(pj_status_t) pjsua_vid_win_get_info( pjsua_vid_win_id wid,
|
|||
|
||||
if (w->is_native) {
|
||||
pjmedia_vid_dev_stream *cap_strm;
|
||||
pjmedia_vid_dev_cap cap = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
|
||||
pjmedia_vid_dev_cap cap = PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW;
|
||||
|
||||
if (!w->vp_cap) {
|
||||
status = PJ_EINVAL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Don't change the "export PJ_VERSION_xxx" style, they are parsed by setup.py
|
||||
export PJ_VERSION_MAJOR := 2
|
||||
export PJ_VERSION_MINOR := 13
|
||||
export PJ_VERSION_REV :=
|
||||
export PJ_VERSION_REV := 1
|
||||
export PJ_VERSION_SUFFIX :=
|
||||
|
||||
export PJ_VERSION := $(PJ_VERSION_MAJOR).$(PJ_VERSION_MINOR)
|
||||
|
|
Loading…
Reference in New Issue