Fixed native iOS preview issue (#3350)
This commit is contained in:
parent
43c745789d
commit
f1e6313389
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue