summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2014-05-07 05:30:29 +0000
committerNanang Izzuddin <nanang@teluu.com>2014-05-07 05:30:29 +0000
commit1e50ea4a7d4915263b88a215e94c45264cee7686 (patch)
treed32c3775bf1e1e8b9a1370b8313aff379c21d25c
parent508132cd773b3e8288d00f90cd31d201d1070f6f (diff)
Re #1762: Fix native preview not shown issue by starting capture session from main thread.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4837 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/src/pjmedia-videodev/ios_dev.m62
1 files changed, 41 insertions, 21 deletions
diff --git a/pjmedia/src/pjmedia-videodev/ios_dev.m b/pjmedia/src/pjmedia-videodev/ios_dev.m
index a7cd2b21..26fd5615 100644
--- a/pjmedia/src/pjmedia-videodev/ios_dev.m
+++ b/pjmedia/src/pjmedia-videodev/ios_dev.m
@@ -96,6 +96,7 @@ struct ios_stream
AVCaptureVideoDataOutput *video_output;
VOutDelegate *vout_delegate;
void *capture_buf;
+ AVCaptureVideoPreviewLayer *prev_layer;
void *render_buf;
pj_size_t render_buf_size;
@@ -714,9 +715,6 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
/* Create view */
ios_init_view(strm);
- CALayer *view_layer = strm->render_view.layer;
- CGRect r = strm->render_view.bounds;
-
/* Preview layer instantiation should be in main thread! */
dispatch_async(dispatch_get_main_queue(), ^{
/* Create preview layer */
@@ -725,9 +723,10 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
layerWithSession:strm->cap_session];
/* Attach preview layer to a UIView */
- prev_layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
- prev_layer.frame = r;
- [view_layer addSublayer:prev_layer];
+ prev_layer.videoGravity = AVLayerVideoGravityResize;
+ prev_layer.frame = strm->render_view.bounds;
+ [strm->render_view.layer addSublayer:prev_layer];
+ strm->prev_layer = prev_layer;
PJ_LOG(4, (THIS_FILE, "Native preview initialized"));
});
@@ -831,6 +830,8 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
strm->param.disp_size.h);
dispatch_async(dispatch_get_main_queue(), ^{
strm->render_view.bounds = r;
+ if (strm->prev_layer)
+ strm->prev_layer.frame = r;
});
return PJ_SUCCESS;
}
@@ -890,7 +891,13 @@ static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
PJ_LOG(4, (THIS_FILE, "Starting iOS video stream"));
if (stream->cap_session) {
- [stream->cap_session startRunning];
+ if ([NSThread isMainThread]) {
+ [stream->cap_session startRunning];
+ } else {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [stream->cap_session startRunning];
+ });
+ }
if (![stream->cap_session isRunning])
return PJ_EUNKNOWN;
@@ -905,7 +912,6 @@ static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
const pjmedia_frame *frame)
{
struct ios_stream *stream = (struct ios_stream*)strm;
- //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (stream->frame_size >= frame->size)
pj_memcpy(stream->render_buf, frame->buf, frame->size);
@@ -913,10 +919,9 @@ static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
pj_memcpy(stream->render_buf, frame->buf, stream->frame_size);
/* Perform video display in a background thread */
- dispatch_async(dispatch_get_main_queue(),
- ^{[stream->vout_delegate update_image];});
-
- //[pool release];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [stream->vout_delegate update_image];
+ });
return PJ_SUCCESS;
}
@@ -930,8 +935,15 @@ static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm)
PJ_LOG(4, (THIS_FILE, "Stopping iOS video stream"));
- if (stream->cap_session && [stream->cap_session isRunning])
- [stream->cap_session stopRunning];
+ if (stream->cap_session && [stream->cap_session isRunning]) {
+ if ([NSThread isMainThread]) {
+ [stream->cap_session stopRunning];
+ } else {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [stream->cap_session stopRunning];
+ });
+ }
+ }
return PJ_SUCCESS;
}
@@ -964,19 +976,27 @@ static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
stream->video_output = nil;
}
+ if (stream->prev_layer) {
+ CALayer *prev_layer = stream->prev_layer;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [prev_layer removeFromSuperlayer];
+ [prev_layer release];
+ });
+ stream->prev_layer = nil;
+ }
+
if (stream->render_view) {
UIView *view = stream->render_view;
- dispatch_async(dispatch_get_main_queue(),
- ^{
- [view removeFromSuperview];
- [view release];
- });
- stream->render_view = NULL;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [view removeFromSuperview];
+ [view release];
+ });
+ stream->render_view = nil;
}
if (stream->render_data_provider) {
CGDataProviderRelease(stream->render_data_provider);
- stream->render_data_provider = NULL;
+ stream->render_data_provider = nil;
}
pj_pool_release(stream->pool);