Changeset 5051


Ignore:
Timestamp:
Apr 8, 2015 1:00:57 AM (5 years ago)
Author:
ming
Message:

Fixed #1837: Fix premature dispatch queue release in iOS capture device

Also add more logs, error checking, and modify the auto release of video output delegate

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/ios_dev.m

    r5002 r5051  
    6666}; 
    6767 
    68 /* qt device info */ 
     68/* ios device info */ 
    6969struct ios_dev_info 
    7070{ 
     
    7373}; 
    7474 
    75 /* qt factory */ 
     75/* ios factory */ 
    7676struct ios_factory 
    7777{ 
     
    112112    AVCaptureVideoDataOutput    *video_output; 
    113113    VOutDelegate                *vout_delegate; 
     114    dispatch_queue_t             queue; 
    114115    void                        *capture_buf; 
    115116    AVCaptureVideoPreviewLayer  *prev_layer; 
     
    628629        strm->cap_session = [[AVCaptureSession alloc] init]; 
    629630        if (!strm->cap_session) { 
     631            PJ_LOG(2, (THIS_FILE, "Unable to create AV capture session")); 
    630632            status = PJ_ENOMEM; 
    631633            goto on_error; 
     
    668670                           deviceInputWithDevice:dev 
    669671                           error: &error]; 
    670         if (!strm->dev_input) { 
     672        if (error || !strm->dev_input) { 
     673            PJ_LOG(2, (THIS_FILE, "Unable to get input capture device")); 
    671674            status = PJMEDIA_EVID_SYSERR; 
    672675            goto on_error; 
    673676        } 
    674         [strm->cap_session addInput:strm->dev_input]; 
    675677         
    676         strm->video_output = [[[AVCaptureVideoDataOutput alloc] init] 
    677                               autorelease]; 
    678         if (!strm->video_output) { 
     678        if ([strm->cap_session canAddInput:strm->dev_input]) { 
     679            [strm->cap_session addInput:strm->dev_input]; 
     680        } else { 
     681            PJ_LOG(2, (THIS_FILE, "Unable to add input capture device")); 
    679682            status = PJMEDIA_EVID_SYSERR; 
    680683            goto on_error; 
    681684        } 
    682          
     685         
     686        strm->video_output = [[AVCaptureVideoDataOutput alloc] init]; 
     687        if (!strm->video_output) { 
     688            PJ_LOG(2, (THIS_FILE, "Unable to create AV video output")); 
     689            status = PJ_ENOMEM; 
     690            goto on_error; 
     691        } 
     692         
     693        /* Configure the video output */ 
    683694        strm->video_output.alwaysDiscardsLateVideoFrames = YES; 
    684         [strm->cap_session addOutput:strm->video_output]; 
    685          
    686         /* Configure the video output */ 
    687         strm->vout_delegate = [VOutDelegate alloc]; 
    688         strm->vout_delegate->stream = strm; 
    689         dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL); 
    690         [strm->video_output setSampleBufferDelegate:strm->vout_delegate 
    691                                               queue:queue]; 
    692         dispatch_release(queue); 
    693          
    694695        strm->video_output.videoSettings = 
    695696            [NSDictionary dictionaryWithObjectsAndKeys: 
    696697                          [NSNumber numberWithInt:ifi->ios_format], 
    697698                          kCVPixelBufferPixelFormatTypeKey, nil]; 
    698          
     699 
     700        strm->vout_delegate = [VOutDelegate alloc]; 
     701        strm->vout_delegate->stream = strm; 
     702        strm->queue = dispatch_queue_create("vout_queue", 
     703                                            DISPATCH_QUEUE_SERIAL); 
     704        [strm->video_output setSampleBufferDelegate:strm->vout_delegate 
     705                            queue:strm->queue]; 
     706         
     707        if ([strm->cap_session canAddOutput:strm->video_output]) { 
     708            [strm->cap_session addOutput:strm->video_output]; 
     709        } else { 
     710            PJ_LOG(2, (THIS_FILE, "Unable to add video data output")); 
     711            status = PJMEDIA_EVID_SYSERR; 
     712            goto on_error; 
     713        } 
     714         
    699715        /* Prepare capture buffer if it's planar format */ 
    700716        if (strm->is_planar) 
     
    819835            if (!strm->render_view) 
    820836                ios_init_view(strm); 
    821              
    822837             
    823838            /* Preview layer instantiation should be in main thread! */ 
     
    10051020        } 
    10061021     
    1007         if (![stream->cap_session isRunning]) 
     1022        if (![stream->cap_session isRunning]) { 
     1023            PJ_LOG(3, (THIS_FILE, "Unable to start iOS capture session")); 
    10081024            return PJ_EUNKNOWN; 
     1025        } 
    10091026    } 
    10101027     
     
    10371054    struct ios_stream *stream = (struct ios_stream*)strm; 
    10381055 
    1039     PJ_UNUSED_ARG(stream); 
    1040  
     1056    if (!stream->cap_session || ![stream->cap_session isRunning]) 
     1057        return PJ_SUCCESS; 
     1058     
    10411059    PJ_LOG(4, (THIS_FILE, "Stopping iOS video stream")); 
    10421060 
    1043     if (stream->cap_session && [stream->cap_session isRunning]) { 
    1044         if ([NSThread isMainThread]) { 
     1061    if ([NSThread isMainThread]) { 
     1062        [stream->cap_session stopRunning]; 
     1063    } else { 
     1064        dispatch_sync(dispatch_get_main_queue(), ^{ 
    10451065            [stream->cap_session stopRunning]; 
    1046         } else { 
    1047             dispatch_sync(dispatch_get_main_queue(), ^{ 
    1048                 [stream->cap_session stopRunning]; 
    1049             }); 
    1050         } 
     1066        }); 
    10511067    } 
    10521068     
     
    10651081     
    10661082    if (stream->cap_session) { 
    1067         [stream->cap_session removeInput:stream->dev_input]; 
     1083        if (stream->dev_input) { 
     1084            [stream->cap_session removeInput:stream->dev_input]; 
     1085            stream->dev_input = nil; 
     1086        } 
    10681087        [stream->cap_session removeOutput:stream->video_output]; 
    10691088        [stream->cap_session release]; 
    10701089        stream->cap_session = nil; 
    1071     }     
    1072     if (stream->dev_input) { 
    1073         stream->dev_input = nil; 
    10741090    } 
    10751091  
     1092    if (stream->video_output) { 
     1093        [stream->video_output release]; 
     1094        stream->video_output = nil; 
     1095    } 
     1096 
    10761097    if (stream->vout_delegate) { 
    10771098        [stream->vout_delegate release]; 
    10781099        stream->vout_delegate = nil; 
    1079     } 
    1080     if (stream->video_output) { 
    1081         stream->video_output = nil; 
    10821100    } 
    10831101 
     
    11051123    } 
    11061124 
     1125    if (stream->queue) { 
     1126        dispatch_release(stream->queue); 
     1127        stream->queue = nil; 
     1128    } 
     1129 
    11071130    pj_pool_release(stream->pool); 
    11081131 
Note: See TracChangeset for help on using the changeset viewer.