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
  • talregev/vlc
  • Managor/vlc
  • abdsaber000/vlc
  • falbrechtskirchinger/vlc
405 results
Show changes
Commits on Source (10)
...@@ -72,11 +72,20 @@ vlc_module_begin () ...@@ -72,11 +72,20 @@ vlc_module_begin ()
set_callbacks(Open, Close) set_callbacks(Open, Close)
vlc_module_end () 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 * AVFoundation Bridge
*****************************************************************************/ *****************************************************************************/
@interface VLCAVDecompressedVideoOutput : AVCaptureVideoDataOutput @interface VLCAVDecompressedVideoOutput :
AVCaptureVideoDataOutput <AVCaptureVideoDataOutputSampleBufferDelegate>
{ {
demux_t *p_avcapture; demux_t *p_avcapture;
...@@ -157,23 +166,22 @@ vlc_module_end () ...@@ -157,23 +166,22 @@ vlc_module_end ()
self.videoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); self.videoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
bytesPerRow = CVPixelBufferGetBytesPerRow(CMSampleBufferGetImageBuffer(sampleBuffer)); bytesPerRow = CVPixelBufferGetBytesPerRow(CMSampleBufferGetImageBuffer(sampleBuffer));
videoDimensionsReady = YES; 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; vlc_tick_t pts;
if ( !currentImageBuffer || currentPts == previousPts )
return 0;
@synchronized (self) @synchronized (self)
{ {
if ( !currentImageBuffer || currentPts == previousPts )
return VLC_TICK_INVALID;
pts = previousPts = currentPts; pts = previousPts = currentPts;
} }
return currentPts; return pts;
} }
- (void)captureOutput:(AVCaptureOutput *)captureOutput - (void)captureOutput:(AVCaptureOutput *)captureOutput
...@@ -187,13 +195,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ...@@ -187,13 +195,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
CVBufferRetain(videoFrame); CVBufferRetain(videoFrame);
[self getVideoDimensions:sampleBuffer]; [self getVideoDimensions:sampleBuffer];
@synchronized (self) { @synchronized (self) {
imageBufferToRelease = currentImageBuffer; imageBufferToRelease = currentImageBuffer;
currentImageBuffer = videoFrame; currentImageBuffer = videoFrame;
currentPts = (vlc_tick_t)presentationtimestamp.value; currentPts = vlc_CMTime_to_tick(presentationtimestamp);
timeScale = (long)presentationtimestamp.timescale; timeScale = (long)presentationtimestamp.timescale;
} }
CVBufferRelease(imageBufferToRelease); CVBufferRelease(imageBufferToRelease);
} }
} }
...@@ -237,16 +246,21 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ...@@ -237,16 +246,21 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
* Struct * Struct
*****************************************************************************/ *****************************************************************************/
typedef struct demux_sys_t @interface VLCAVCaptureDemux : NSObject {
{ demux_t *_demux;
CFTypeRef _Nullable session; // AVCaptureSession AVCaptureSession *_session;
CFTypeRef _Nullable device; // AVCaptureDevice AVCaptureDevice *_device;
CFTypeRef _Nullable output; // VLCAVDecompressedVideoOutput VLCAVDecompressedVideoOutput *_output;
es_out_id_t *p_es_video; es_out_id_t *_es_video;
es_format_t fmt; es_format_t _fmt;
int height, width; int _height, _width;
BOOL b_es_setup; }
} demux_sys_t;
- (VLCAVCaptureDemux*)init:(demux_t *)demux;
- (int)demux;
- (vlc_tick_t)pts;
- (void)dealloc;
@end
/***************************************************************************** /*****************************************************************************
* Open: * Open:
...@@ -254,8 +268,82 @@ typedef struct demux_sys_t ...@@ -254,8 +268,82 @@ typedef struct demux_sys_t
static int Open(vlc_object_t *p_this) static int Open(vlc_object_t *p_this)
{ {
demux_t *p_demux = (demux_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; NSString *avf_currdevice_uid;
NSArray *myVideoDevices; NSArray *myVideoDevices;
NSError *o_returnedError; NSError *o_returnedError;
...@@ -266,174 +354,135 @@ static int Open(vlc_object_t *p_this) ...@@ -266,174 +354,135 @@ static int Open(vlc_object_t *p_this)
char *psz_uid = NULL; char *psz_uid = NULL;
if (p_demux->out == NULL) _demux = p_demux;
return VLC_EGENERIC;
@autoreleasepool {
if (p_demux->psz_location && *p_demux->psz_location)
psz_uid = strdup(p_demux->psz_location);
msg_Dbg(p_demux, "avcapture uid = %s", psz_uid); if (_demux->psz_location && *_demux->psz_location)
avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid]; psz_uid = strdup(_demux->psz_location);
/* Set up p_demux */ msg_Dbg(_demux, "avcapture uid = %s", psz_uid);
p_demux->pf_demux = Demux; avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid];
p_demux->pf_control = Control;
p_demux->p_sys = p_sys = calloc(1, sizeof(demux_sys_t)); myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
if ( !p_sys ) arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]];
return VLC_ENOMEM; if ( [myVideoDevices count] == 0 )
{
myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] vlc_dialog_display_error(_demux, _("No video devices found"),
arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]]; _("Your Mac does not seem to be equipped with a suitable video input device. "
if ( [myVideoDevices count] == 0 ) "Please check your connectors and drivers."));
{ msg_Err(_demux, "Can't find any suitable video device");
vlc_dialog_display_error(p_demux, _("No video devices found"), return nil;
_("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;
}
deviceCount = [myVideoDevices count]; deviceCount = [myVideoDevices count];
for ( ivideo = 0; ivideo < deviceCount; ivideo++ ) for ( ivideo = 0; ivideo < deviceCount; ivideo++ )
{ {
AVCaptureDevice *avf_device; AVCaptureDevice *avf_device;
avf_device = [myVideoDevices objectAtIndex:ivideo]; avf_device = [myVideoDevices objectAtIndex:ivideo];
msg_Dbg(p_demux, "avcapture %i/%i %s %s", ivideo, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]); 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]) { if ([[[avf_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:avf_currdevice_uid]) {
break; break;
}
} }
}
if ( ivideo < [myVideoDevices count] ) if ( ivideo < [myVideoDevices count] )
{ {
p_sys->device = CFBridgingRetain([myVideoDevices objectAtIndex:ivideo]); _device = [myVideoDevices objectAtIndex:ivideo];
} }
else else
{ {
msg_Dbg(p_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]); msg_Dbg(_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]);
p_sys->device = CFBridgingRetain([AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]); _device = [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 ( [(__bridge AVCaptureDevice *)p_sys->device isInUseByAnotherApplication] == YES ) if ( !_device )
{ {
msg_Err(p_demux, "default capture device is exclusively in use by another application"); vlc_dialog_display_error(_demux, _("No video devices found"),
goto error; _("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, *)) { AVCaptureDevice *device = _device;
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;
}
}
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 ) if (@available(macOS 10.14, *)) {
{ msg_Dbg(_demux, "Check user consent for access to the video device");
msg_Err(p_demux, "can't create a valid capture input facility: %s (%ld)",[[o_returnedError localizedDescription] UTF8String], [o_returnedError code]);
goto error; 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)); int chroma = VLC_CODEC_BGRA;
es_format_Init(&p_sys->fmt, VIDEO_ES, chroma);
p_sys->session = CFBridgingRetain([[AVCaptureSession alloc] init]); memset(&_fmt, 0, sizeof(es_format_t));
[(__bridge AVCaptureSession *)p_sys->session addInput:input]; es_format_Init(&_fmt, VIDEO_ES, chroma);
p_sys->output = CFBridgingRetain([[VLCAVDecompressedVideoOutput alloc] initWithDemux:p_demux]); _session = [[AVCaptureSession alloc] init];
[(__bridge AVCaptureSession *)p_sys->session addOutput:(__bridge VLCAVDecompressedVideoOutput *)p_sys->output];
dispatch_queue_t queue = dispatch_queue_create("avCaptureQueue", NULL); [_session addInput:input];
[(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setSampleBufferDelegate:(__bridge id)p_sys->output queue:queue];
dispatch_release(queue);
[(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; _output = [[VLCAVDecompressedVideoOutput alloc] initWithDemux:_demux];
[(__bridge AVCaptureSession *)p_sys->session startRunning];
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; [_output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
error: [_session startRunning];
msg_Err(p_demux, "Error");
input = nil;
free(p_sys); input = nil;
return VLC_EGENERIC; msg_Dbg(_demux, "AVCapture: Video device ready!");
}
}
/***************************************************************************** return self;
* 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);
}
} }
/***************************************************************************** - (int)demux
* Demux:
*****************************************************************************/
static int Demux(demux_t *p_demux)
{ {
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block; block_t *p_block;
@autoreleasepool { @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 ) if ( !p_block )
{ {
msg_Err(p_demux, "cannot get block"); msg_Err(_demux, "cannot get block");
return 0; 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 ) if ( !p_block->i_pts )
{ {
...@@ -442,54 +491,41 @@ static int Demux(demux_t *p_demux) ...@@ -442,54 +491,41 @@ static int Demux(demux_t *p_demux)
vlc_tick_sleep(VLC_HARD_MIN_SLEEP); vlc_tick_sleep(VLC_HARD_MIN_SLEEP);
return 1; 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]; _fmt.video.i_frame_rate = 1;
msg_Dbg(p_demux, "using frame rate base: %i", p_sys->fmt.video.i_frame_rate_base); _fmt.video.i_frame_rate_base = [_output timeScale];
p_sys->width = p_sys->fmt.video.i_width = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output width]; msg_Dbg(_demux, "using frame rate base: %i", _fmt.video.i_frame_rate_base);
p_sys->height = p_sys->fmt.video.i_height = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output height]; _width
p_sys->p_es_video = es_out_Add(p_demux->out, &p_sys->fmt); = _fmt.video.i_width
msg_Dbg(p_demux, "added new video es %4.4s %dx%d", (char*)&p_sys->fmt.i_codec, p_sys->width, p_sys->height); = _fmt.video.i_visible_width
p_sys->b_es_setup = YES; = [_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_SetPCR(_demux->out, p_block->i_pts);
es_out_Send(p_demux->out, p_sys->p_es_video, p_block); es_out_Send(_demux->out, _es_video, p_block);
} }
return 1; return 1;
} }
/***************************************************************************** - (vlc_tick_t)pts
* Control:
*****************************************************************************/
static int Control(demux_t *p_demux, int i_query, va_list args)
{ {
bool *pb; return [_output currentPts];
}
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;
default: - (void)dealloc
return VLC_EGENERIC; {
} // Perform this on main thread, as the framework itself will sometimes try to synchronously
return VLC_EGENERIC; // work on main thread. And this will create a dead lock.
[_session performSelectorOnMainThread:@selector(stopRunning) withObject:nil waitUntilDone:NO];
} }
@end