X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fqtcapture.m;h=eac2e6f005426e7a80997989869887cfea21307a;hb=62dd14548820fb0966e6b90d586183f74a427e4b;hp=af76dc333967f598f295ea91736afe77c6fb5ca5;hpb=01744abf01e4a5389a19bfdabfa1c613c6c363c1;p=vlc diff --git a/modules/access/qtcapture.m b/modules/access/qtcapture.m index af76dc3339..eac2e6f005 100644 --- a/modules/access/qtcapture.m +++ b/modules/access/qtcapture.m @@ -35,8 +35,10 @@ #include #include #include +#include #import +#import /***************************************************************************** * Local prototypes @@ -67,6 +69,7 @@ vlc_module_end(); { CVImageBufferRef currentImageBuffer; mtime_t currentPts; + mtime_t previousPts; } - (id)init; - (void)outputVideoFrame:(CVImageBufferRef)videoFrame withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection; @@ -81,6 +84,7 @@ vlc_module_end(); { currentImageBuffer = nil; currentPts = 0; + previousPts = 0; } return self; } @@ -106,7 +110,11 @@ vlc_module_end(); { imageBufferToRelease = currentImageBuffer; currentImageBuffer = videoFrame; - currentPts = [sampleBuffer presentationTime].timeValue; + currentPts = (mtime_t)(1000000L / [sampleBuffer presentationTime].timeScale * [sampleBuffer presentationTime].timeValue); + + /* Try to use hosttime of the sample if available, because iSight Pts seems broken */ + NSNumber *hosttime = (NSNumber *)[sampleBuffer attributeForKey:QTSampleBufferHostTimeAttribute]; + if( hosttime ) currentPts = (mtime_t)AudioConvertHostTimeToNanos([hosttime unsignedLongLongValue])/1000; } CVBufferRelease(imageBufferToRelease); } @@ -116,13 +124,13 @@ vlc_module_end(); CVImageBufferRef imageBuffer; mtime_t pts; - if(!currentImageBuffer) + if(!currentImageBuffer || currentPts == previousPts ) return 0; @synchronized (self) { imageBuffer = CVBufferRetain(currentImageBuffer); - pts = currentPts; + pts = previousPts = currentPts; CVPixelBufferLockBaseAddress(imageBuffer, 0); void * pixels = CVPixelBufferGetBaseAddress(imageBuffer); @@ -210,24 +218,35 @@ static int Open( vlc_object_t *p_this ) msg_Dbg( p_demux, "QTCapture Probed" ); QTCaptureDeviceInput * input = nil; + NSError *o_returnedError; p_sys->device = [QTCaptureDevice defaultInputDeviceWithMediaType: QTMediaTypeVideo]; if( !p_sys->device ) { + intf_UserFatal( p_demux, true, _("No Input device found"), + _("Your Mac does not seem to be equipped with a suitable input device. " + "Please check your connectors and drivers.") ); msg_Err( p_demux, "Can't find any Video device" ); + goto error; } - if( ![p_sys->device open: nil /* FIXME */] ) + if( ![p_sys->device open: &o_returnedError] ) { - msg_Err( p_demux, "Can't open any Video device" ); + msg_Err( p_demux, "Unable to open the capture device (%i)", [o_returnedError code] ); + goto error; + } + + if( [p_sys->device isInUseByAnotherApplication] == YES ) + { + msg_Err( p_demux, "default capture device is exclusively in use by another application" ); goto error; } input = [[QTCaptureDeviceInput alloc] initWithDevice: p_sys->device]; - if( !p_sys->device ) + if( !input ) { - msg_Err( p_demux, "Can't create a capture session" ); + msg_Err( p_demux, "can't create a valid capture input facility" ); goto error; } @@ -240,17 +259,17 @@ static int Open( vlc_object_t *p_this ) p_sys->session = [[QTCaptureSession alloc] init]; - bool ret = [p_sys->session addInput:input error:nil /* FIXME */]; + bool ret = [p_sys->session addInput:input error: &o_returnedError]; if( !ret ) { - msg_Err( p_demux, "Can't add the video device as input" ); + msg_Err( p_demux, "default video capture device could not be added to capture session (%i)", [o_returnedError code] ); goto error; } - ret = [p_sys->session addOutput:p_sys->output error:nil /* FIXME */]; + ret = [p_sys->session addOutput:p_sys->output error: &o_returnedError]; if( !ret ) { - msg_Err( p_demux, "Can't get any output output" ); + msg_Err( p_demux, "output could not be added to capture session (%i)", [o_returnedError code] ); goto error; } @@ -303,10 +322,15 @@ static void Close( vlc_object_t *p_this ) demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys = p_demux->p_sys; - [p_sys->session stopRunning]; - [p_sys->output release]; - [p_sys->session release]; - [p_sys->device release]; + /* Hack: if libvlc was killed, main interface thread was, + * and poor QTKit needs it, so don't tell him. + * Else we dead lock. */ + if( vlc_object_alive(p_this->p_libvlc)) + { + [p_sys->session stopRunning]; + [p_sys->output release]; + [p_sys->session release]; + } free( p_sys ); [pool release]; @@ -341,12 +365,10 @@ static int Demux( demux_t *p_demux ) /* Nothing to display yet, just forget */ block_Release( p_block ); [pool release]; + msleep( 10000 ); return 1; } - /* FIXME */ - p_block->i_pts = mdate(); - es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es_video, p_block ); @@ -378,12 +400,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) *pi64 = (int64_t)DEFAULT_PTS_DELAY; return VLC_SUCCESS; - case DEMUX_GET_TIME: - pi64 = (int64_t*)va_arg( args, int64_t * ); - *pi64 = mdate(); - return VLC_SUCCESS; - - /* TODO implement others */ default: return VLC_EGENERIC; }