Changeset 5054 for pjproject


Ignore:
Timestamp:
Apr 8, 2015 10:09:37 AM (9 years ago)
Author:
ming
Message:

Re #1837: Fix dispatch queue problem in iOS capture device (crash in enc_clock_cb)

File:
1 edited

Legend:

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

    r5051 r5054  
    107107    unsigned                frame_size;         /**< Frame size (bytes)*/ 
    108108    pj_bool_t               is_planar; 
     109    NSLock                 *frame_lock; 
     110    void                   *capture_buf; 
    109111     
    110112    AVCaptureSession            *cap_session; 
     
    113115    VOutDelegate                *vout_delegate; 
    114116    dispatch_queue_t             queue; 
    115     void                        *capture_buf; 
    116117    AVCaptureVideoPreviewLayer  *prev_layer; 
    117118     
     
    123124    pj_timestamp         frame_ts; 
    124125    unsigned             ts_inc; 
    125  
    126     pj_bool_t            thread_initialized; 
    127     pj_thread_desc       thread_desc; 
    128     pj_thread_t         *thread; 
    129126}; 
    130127 
     
    158155                                      const void *value); 
    159156static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm); 
     157static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm, 
     158                                        pjmedia_frame *frame); 
    160159static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    161160                                        const pjmedia_frame *frame); 
     
    181180    &ios_stream_set_cap, 
    182181    &ios_stream_start, 
    183     NULL, 
     182    &ios_stream_get_frame, 
    184183    &ios_stream_put_frame, 
    185184    &ios_stream_stop, 
     
    262261            pj_ansi_strncpy(qdi->info.driver, "iOS", sizeof(qdi->info.driver)); 
    263262            qdi->info.dir = PJMEDIA_DIR_CAPTURE; 
    264             qdi->info.has_callback = PJ_TRUE; 
     263            qdi->info.has_callback = PJ_FALSE; 
    265264            qdi->info.caps = PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW | 
    266265                             PJMEDIA_VID_DEV_CAP_SWITCH; 
     
    436435                      fromConnection:(AVCaptureConnection *)connection 
    437436{ 
    438     pjmedia_frame frame = {0}; 
    439437    CVImageBufferRef img; 
     438 
     439    /* Refrain from calling pjlib functions which require thread registration 
     440     * here, since according to the doc, dispatch queue cannot guarantee 
     441     * the reliability of underlying functions required by PJSIP to perform 
     442     * the registration, such as pthread_self() and pthread_getspecific()/ 
     443     * pthread_setspecific(). 
     444     */ 
    440445 
    441446    if (!sampleBuffer) 
     
    448453    CVPixelBufferLockBaseAddress(img, kCVPixelBufferLock_ReadOnly); 
    449454     
    450     frame.type = PJMEDIA_FRAME_TYPE_VIDEO; 
    451     frame.size = stream->frame_size; 
    452     frame.timestamp.u64 = stream->frame_ts.u64; 
    453      
     455 
     456    [stream->frame_lock lock]; 
    454457    if (stream->is_planar && stream->capture_buf) { 
    455458        if (stream->param.fmt.id == PJMEDIA_FORMAT_I420) { 
     
    499502                } 
    500503            } 
    501  
    502             frame.buf = stream->capture_buf; 
    503504        } 
    504505    } else { 
    505         frame.buf = CVPixelBufferGetBaseAddress(img); 
    506     } 
    507      
    508     if (stream->vid_cb.capture_cb) { 
    509         if (stream->thread_initialized == 0 || !pj_thread_is_registered()) 
    510         { 
    511             pj_bzero(stream->thread_desc, sizeof(pj_thread_desc)); 
    512             pj_thread_register("ios_vdev", stream->thread_desc, 
    513                                &stream->thread); 
    514             stream->thread_initialized = 1; 
    515         } 
    516  
    517         (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &frame); 
     506        pj_memcpy(stream->capture_buf, CVPixelBufferGetBaseAddress(img), 
     507                  stream->frame_size); 
    518508    } 
    519509 
    520510    stream->frame_ts.u64 += stream->ts_inc; 
     511    [stream->frame_lock unlock]; 
    521512     
    522513    /* Unlock the pixel buffer */ 
     
    524515} 
    525516@end 
     517 
     518static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm, 
     519                                        pjmedia_frame *frame) 
     520{ 
     521    struct ios_stream *stream = (struct ios_stream *)strm; 
     522 
     523    frame->type = PJMEDIA_FRAME_TYPE_VIDEO; 
     524    frame->bit_info = 0; 
     525    pj_assert(frame->size >= stream->frame_size); 
     526    frame->size = stream->frame_size; 
     527    frame->timestamp.u64 = stream->frame_ts.u64; 
     528     
     529    [stream->frame_lock lock]; 
     530    pj_memcpy(frame->buf, stream->capture_buf, stream->frame_size); 
     531    [stream->frame_lock unlock]; 
     532     
     533    return PJ_SUCCESS; 
     534} 
     535 
    526536 
    527537static ios_fmt_info* get_ios_format_info(pjmedia_format_id id) 
     
    713723        } 
    714724         
    715         /* Prepare capture buffer if it's planar format */ 
    716         if (strm->is_planar) 
    717             strm->capture_buf = pj_pool_alloc(strm->pool, strm->frame_size); 
    718          
     725        strm->capture_buf = pj_pool_alloc(strm->pool, strm->frame_size); 
     726        strm->frame_lock = [[NSLock alloc]init]; 
     727         
    719728        /* Native preview */ 
    720729        if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) { 
     
    11271136        stream->queue = nil; 
    11281137    } 
     1138     
     1139    if (stream->frame_lock) { 
     1140        [stream->frame_lock release]; 
     1141        stream->frame_lock = nil; 
     1142    } 
    11291143 
    11301144    pj_pool_release(stream->pool); 
Note: See TracChangeset for help on using the changeset viewer.