Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
401 results
Show changes
Commits on Source (10)
......@@ -72,11 +72,20 @@ vlc_module_begin ()
set_callbacks(Open, Close)
vlc_module_end ()
static vlc_tick_t vlc_CMTime_to_tick(CMTime timestamp)
{
CMTime scaled = CMTimeConvertScale(
timestamp, CLOCK_FREQ,
kCMTimeRoundingMethod_Default);
return VLC_TICK_0 + scaled.value;
}
/*****************************************************************************
* AVFoundation Bridge
*****************************************************************************/
@interface VLCAVDecompressedVideoOutput : AVCaptureVideoDataOutput
@interface VLCAVDecompressedVideoOutput :
AVCaptureVideoDataOutput <AVCaptureVideoDataOutputSampleBufferDelegate>
{
demux_t *p_avcapture;
......@@ -157,23 +166,22 @@ vlc_module_end ()
self.videoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
bytesPerRow = CVPixelBufferGetBytesPerRow(CMSampleBufferGetImageBuffer(sampleBuffer));
videoDimensionsReady = YES;
msg_Dbg(p_avcapture, "Dimensionns obtained height:%i width:%i bytesPerRow:%lu", [self height], [self width], bytesPerRow);
msg_Dbg(p_avcapture, "Dimensions obtained height:%i width:%i bytesPerRow:%lu", [self height], [self width], bytesPerRow);
}
}
-(vlc_tick_t)currentPts
- (vlc_tick_t)currentPts
{
vlc_tick_t pts;
if ( !currentImageBuffer || currentPts == previousPts )
return 0;
@synchronized (self)
{
if ( !currentImageBuffer || currentPts == previousPts )
return VLC_TICK_INVALID;
pts = previousPts = currentPts;
}
return currentPts;
return pts;
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
......@@ -187,13 +195,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
CVBufferRetain(videoFrame);
[self getVideoDimensions:sampleBuffer];
@synchronized (self) {
imageBufferToRelease = currentImageBuffer;
currentImageBuffer = videoFrame;
currentPts = (vlc_tick_t)presentationtimestamp.value;
currentPts = vlc_CMTime_to_tick(presentationtimestamp);
timeScale = (long)presentationtimestamp.timescale;
}
CVBufferRelease(imageBufferToRelease);
}
}
......@@ -237,16 +246,21 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
* Struct
*****************************************************************************/
typedef struct demux_sys_t
{
CFTypeRef _Nullable session; // AVCaptureSession
CFTypeRef _Nullable device; // AVCaptureDevice
CFTypeRef _Nullable output; // VLCAVDecompressedVideoOutput
es_out_id_t *p_es_video;
es_format_t fmt;
int height, width;
BOOL b_es_setup;
} demux_sys_t;
@interface VLCAVCaptureDemux : NSObject {
demux_t *_demux;
AVCaptureSession *_session;
AVCaptureDevice *_device;
VLCAVDecompressedVideoOutput *_output;
es_out_id_t *_es_video;
es_format_t _fmt;
int _height, _width;
}
- (VLCAVCaptureDemux*)init:(demux_t *)demux;
- (int)demux;
- (vlc_tick_t)pts;
- (void)dealloc;
@end
/*****************************************************************************
* Open:
......@@ -254,8 +268,82 @@ typedef struct demux_sys_t
static int Open(vlc_object_t *p_this)
{
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = NULL;
if (p_demux->out == NULL)
return VLC_EGENERIC;
@autoreleasepool {
VLCAVCaptureDemux *demux = [[VLCAVCaptureDemux alloc] init:p_demux];
if (demux == nil)
return VLC_EGENERIC;
p_demux->p_sys = (__bridge_retained void*)demux;
}
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close(vlc_object_t *p_this)
{
demux_t *p_demux = (demux_t*)p_this;
VLCAVCaptureDemux *demux =
(__bridge_transfer VLCAVCaptureDemux*)p_demux->p_sys;
/* Signal ARC we won't use those references anymore. */
p_demux->p_sys = nil;
demux = nil;
}
/*****************************************************************************
* Demux:
*****************************************************************************/
static int Demux(demux_t *p_demux)
{
VLCAVCaptureDemux *demux = (__bridge VLCAVCaptureDemux *)p_demux->p_sys;
return [demux demux];
}
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control(demux_t *p_demux, int i_query, va_list args)
{
VLCAVCaptureDemux *demux = (__bridge VLCAVCaptureDemux *)p_demux->p_sys;
bool *pb;
switch( i_query )
{
/* Special for access_demux */
case DEMUX_CAN_PAUSE:
case DEMUX_CAN_SEEK:
case DEMUX_SET_PAUSE_STATE:
case DEMUX_CAN_CONTROL_PACE:
pb = va_arg(args, bool *);
*pb = false;
return VLC_SUCCESS;
case DEMUX_GET_PTS_DELAY:
*va_arg(args, vlc_tick_t *) =
VLC_TICK_FROM_MS(var_InheritInteger(p_demux, "live-caching"));
return VLC_SUCCESS;
case DEMUX_GET_TIME:
*va_arg(args, vlc_tick_t *) = [demux pts];
return VLC_SUCCESS;
default:
return VLC_EGENERIC;
}
return VLC_EGENERIC;
}
@implementation VLCAVCaptureDemux
- (VLCAVCaptureDemux *)init:(demux_t *)p_demux
{
NSString *avf_currdevice_uid;
NSArray *myVideoDevices;
NSError *o_returnedError;
......@@ -266,174 +354,135 @@ static int Open(vlc_object_t *p_this)
char *psz_uid = NULL;
if (p_demux->out == NULL)
return VLC_EGENERIC;
@autoreleasepool {
if (p_demux->psz_location && *p_demux->psz_location)
psz_uid = strdup(p_demux->psz_location);
_demux = p_demux;
msg_Dbg(p_demux, "avcapture uid = %s", psz_uid);
avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid];
if (_demux->psz_location && *_demux->psz_location)
psz_uid = strdup(_demux->psz_location);
/* Set up p_demux */
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
msg_Dbg(_demux, "avcapture uid = %s", psz_uid);
avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid];
p_demux->p_sys = p_sys = calloc(1, sizeof(demux_sys_t));
if ( !p_sys )
return VLC_ENOMEM;
myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]];
if ( [myVideoDevices count] == 0 )
{
vlc_dialog_display_error(p_demux, _("No video devices found"),
_("Your Mac does not seem to be equipped with a suitable video input device. "
"Please check your connectors and drivers."));
msg_Err(p_demux, "Can't find any suitable video device");
goto error;
}
myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]];
if ( [myVideoDevices count] == 0 )
{
vlc_dialog_display_error(_demux, _("No video devices found"),
_("Your Mac does not seem to be equipped with a suitable video input device. "
"Please check your connectors and drivers."));
msg_Err(_demux, "Can't find any suitable video device");
return nil;
}
deviceCount = [myVideoDevices count];
for ( ivideo = 0; ivideo < deviceCount; ivideo++ )
{
AVCaptureDevice *avf_device;
avf_device = [myVideoDevices objectAtIndex:ivideo];
msg_Dbg(p_demux, "avcapture %i/%i %s %s", ivideo, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]);
if ([[[avf_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:avf_currdevice_uid]) {
break;
}
deviceCount = [myVideoDevices count];
for ( ivideo = 0; ivideo < deviceCount; ivideo++ )
{
AVCaptureDevice *avf_device;
avf_device = [myVideoDevices objectAtIndex:ivideo];
msg_Dbg(_demux, "avcapture %i/%i %s %s", ivideo, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]);
if ([[[avf_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:avf_currdevice_uid]) {
break;
}
}
if ( ivideo < [myVideoDevices count] )
{
p_sys->device = CFBridgingRetain([myVideoDevices objectAtIndex:ivideo]);
}
else
{
msg_Dbg(p_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]);
p_sys->device = CFBridgingRetain([AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]);
}
if ( !p_sys->device )
{
vlc_dialog_display_error(p_demux, _("No video devices 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 suitable video device");
goto error;
}
if ( ivideo < [myVideoDevices count] )
{
_device = [myVideoDevices objectAtIndex:ivideo];
}
else
{
msg_Dbg(_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]);
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
if ( [(__bridge AVCaptureDevice *)p_sys->device isInUseByAnotherApplication] == YES )
{
msg_Err(p_demux, "default capture device is exclusively in use by another application");
goto error;
}
if ( !_device )
{
vlc_dialog_display_error(_demux, _("No video devices found"),
_("Your Mac does not seem to be equipped with a suitable input device. "
"Please check your connectors and drivers."));
msg_Err(_demux, "Can't find any suitable video device");
return nil;
}
if (@available(macOS 10.14, *)) {
msg_Dbg(p_demux, "Check user consent for access to the video device");
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block bool accessGranted = NO;
[AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler:^(BOOL granted) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
} ];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
if (!accessGranted) {
msg_Err(p_demux, "Can't use the video device as access has not been granted by the user");
vlc_dialog_display_error(p_demux, _("Problem accessing a system resource"),
_("Please open \"System Preferences\" -> \"Security & Privacy\" "
"and allow VLC to access your camera."));
goto error;
}
}
AVCaptureDevice *device = _device;
input = [AVCaptureDeviceInput deviceInputWithDevice:(__bridge AVCaptureDevice *)p_sys->device error:&o_returnedError];
if ( [device isInUseByAnotherApplication] == YES )
{
msg_Err(_demux, "default capture device is exclusively in use by another application");
return nil;
}
if ( !input )
{
msg_Err(p_demux, "can't create a valid capture input facility: %s (%ld)",[[o_returnedError localizedDescription] UTF8String], [o_returnedError code]);
goto error;
if (@available(macOS 10.14, *)) {
msg_Dbg(_demux, "Check user consent for access to the video device");
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block bool accessGranted = NO;
[AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler:^(BOOL granted) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
} ];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
if (!accessGranted) {
msg_Err(_demux, "Can't use the video device as access has not been granted by the user");
vlc_dialog_display_error(_demux, _("Problem accessing a system resource"),
_("Please open \"System Preferences\" -> \"Security & Privacy\" "
"and allow VLC to access your camera."));
return nil;
}
}
input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&o_returnedError];
int chroma = VLC_CODEC_RGB32;
if ( !input )
{
msg_Err(_demux, "can't create a valid capture input facility: %s (%ld)",[[o_returnedError localizedDescription] UTF8String], [o_returnedError code]);
return nil;
}
memset(&p_sys->fmt, 0, sizeof(es_format_t));
es_format_Init(&p_sys->fmt, VIDEO_ES, chroma);
int chroma = VLC_CODEC_BGRA;
p_sys->session = CFBridgingRetain([[AVCaptureSession alloc] init]);
[(__bridge AVCaptureSession *)p_sys->session addInput:input];
memset(&_fmt, 0, sizeof(es_format_t));
es_format_Init(&_fmt, VIDEO_ES, chroma);
p_sys->output = CFBridgingRetain([[VLCAVDecompressedVideoOutput alloc] initWithDemux:p_demux]);
[(__bridge AVCaptureSession *)p_sys->session addOutput:(__bridge VLCAVDecompressedVideoOutput *)p_sys->output];
_session = [[AVCaptureSession alloc] init];
dispatch_queue_t queue = dispatch_queue_create("avCaptureQueue", NULL);
[(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setSampleBufferDelegate:(__bridge id)p_sys->output queue:queue];
dispatch_release(queue);
[_session addInput:input];
[(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[(__bridge AVCaptureSession *)p_sys->session startRunning];
_output = [[VLCAVDecompressedVideoOutput alloc] initWithDemux:_demux];
input = nil;
[_session addOutput:_output];
msg_Dbg(p_demux, "AVCapture: Video device ready!");
dispatch_queue_t queue = dispatch_queue_create("avCaptureQueue", NULL);
[_output setSampleBufferDelegate:_output queue:queue];
dispatch_release(queue);
return VLC_SUCCESS;
error:
msg_Err(p_demux, "Error");
input = nil;
[_output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[_session startRunning];
free(p_sys);
input = nil;
return VLC_EGENERIC;
}
}
msg_Dbg(_demux, "AVCapture: Video device ready!");
/*****************************************************************************
* Close:
*****************************************************************************/
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;
@autoreleasepool {
msg_Dbg(p_demux,"Close AVCapture");
// Perform this on main thread, as the framework itself will sometimes try to synchronously
// work on main thread. And this will create a dead lock.
[(__bridge AVCaptureSession *)p_sys->session performSelectorOnMainThread:@selector(stopRunning) withObject:nil waitUntilDone:NO];
CFBridgingRelease(p_sys->output);
CFBridgingRelease(p_sys->session);
free(p_sys);
}
return self;
}
/*****************************************************************************
* Demux:
*****************************************************************************/
static int Demux(demux_t *p_demux)
- (int)demux
{
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block;
@autoreleasepool {
@synchronized ( p_sys->output )
@synchronized(_output)
{
p_block = block_Alloc([(__bridge VLCAVDecompressedVideoOutput *)p_sys->output width] * [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output bytesPerRow]);
p_block = block_Alloc([_output width] * [_output bytesPerRow]);
if ( !p_block )
{
msg_Err(p_demux, "cannot get block");
msg_Err(_demux, "cannot get block");
return 0;
}
p_block->i_pts = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output copyCurrentFrameToBuffer: p_block->p_buffer];
p_block->i_pts = [_output copyCurrentFrameToBuffer: p_block->p_buffer];
if ( !p_block->i_pts )
{
......@@ -442,54 +491,41 @@ static int Demux(demux_t *p_demux)
vlc_tick_sleep(VLC_HARD_MIN_SLEEP);
return 1;
}
else if ( !p_sys->b_es_setup )
else if ( !_es_video )
{
p_sys->fmt.video.i_frame_rate_base = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output timeScale];
msg_Dbg(p_demux, "using frame rate base: %i", p_sys->fmt.video.i_frame_rate_base);
p_sys->width = p_sys->fmt.video.i_width = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output width];
p_sys->height = p_sys->fmt.video.i_height = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output height];
p_sys->p_es_video = es_out_Add(p_demux->out, &p_sys->fmt);
msg_Dbg(p_demux, "added new video es %4.4s %dx%d", (char*)&p_sys->fmt.i_codec, p_sys->width, p_sys->height);
p_sys->b_es_setup = YES;
_fmt.video.i_frame_rate = 1;
_fmt.video.i_frame_rate_base = [_output timeScale];
msg_Dbg(_demux, "using frame rate base: %i", _fmt.video.i_frame_rate_base);
_width
= _fmt.video.i_width
= _fmt.video.i_visible_width
= [_output width];
_height
= _fmt.video.i_height
= _fmt.video.i_visible_height
= [_output height];
_fmt.video.i_chroma = _fmt.i_codec;
_es_video = es_out_Add(_demux->out, &_fmt);
video_format_Print(&_demux->obj, "added new video es", &_fmt.video);
}
}
es_out_SetPCR(p_demux->out, p_block->i_pts);
es_out_Send(p_demux->out, p_sys->p_es_video, p_block);
es_out_SetPCR(_demux->out, p_block->i_pts);
es_out_Send(_demux->out, _es_video, p_block);
}
return 1;
}
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control(demux_t *p_demux, int i_query, va_list args)
- (vlc_tick_t)pts
{
bool *pb;
switch( i_query )
{
/* Special for access_demux */
case DEMUX_CAN_PAUSE:
case DEMUX_CAN_SEEK:
case DEMUX_SET_PAUSE_STATE:
case DEMUX_CAN_CONTROL_PACE:
pb = va_arg(args, bool *);
*pb = false;
return VLC_SUCCESS;
case DEMUX_GET_PTS_DELAY:
*va_arg(args, vlc_tick_t *) =
VLC_TICK_FROM_MS(var_InheritInteger(p_demux, "live-caching"));
return VLC_SUCCESS;
case DEMUX_GET_TIME:
*va_arg(args, vlc_tick_t *) = vlc_tick_now();
return VLC_SUCCESS;
return [_output currentPts];
}
default:
return VLC_EGENERIC;
}
return VLC_EGENERIC;
- (void)dealloc
{
// Perform this on main thread, as the framework itself will sometimes try to synchronously
// work on main thread. And this will create a dead lock.
[_session performSelectorOnMainThread:@selector(stopRunning) withObject:nil waitUntilDone:NO];
}
@end