15 ottobre 2009

Hidden Gems of Snow Leopard: IOSurface (with video in)

Video input

I've modified the command line tool to accept some more params, in order to use as frame source a video input. The code, thanks to the QTCapture framework, is pretty straightforward, and it's interesting to note that very little was needed to get it working. Clearly, although with little documentation, IOSurface integrates perfectly in the existing technologies!


Previous posts:

10 ottobre 2009

Hidden Gems of Snow Leopard: IOSurface (again)

The QCPlugin

To extend the previous sample, I've now added a Quartz Composer plugin that spawns the CLI application: it's also possible to choose at compilation time (through a #define) if the image has to be provided to QC as a GL texture or a pixel buffer.
A sample composition has been included in the code.

Notes
  • The embedded CLI application is set as a dependency for the other 2 targets in the project, and should be compiled automatically: however, in certain cases it appears that Xcode "forgets" to apply the build flags, and tries to compile in 64 bits (that fails, as Quicktime doesn't exist in that universe). To solve this issue, compile the IOSurfaceCLI target separately.
  • A bug seems to affect Quartz Composer whenever a movie is started and stopped multiple times: the projection matrix, for some reason, isn't reset, and the frame appears much bigger than it should. A bug report has been posted to Apple.


Other posts on the same argument:

25 settembre 2009

Hidden Gems of Snow Leopard: IOSurface

Snow Leopard may have looked not so different from its predecessor from the average user point of view: however, for developers like myself, a lot of things have changed, some well advertised (say, GCD, OpenCL and 64 bits), some still to discover. A good overview can be found at Ars Technica.
As one of the long overdue issues, not to mention all the limitations derived from its venerable age, Apple has introduced a first step to the future of the old Quicktime (that will stay in 32 bit universe) with the new Quicktime X: however, Quicktime isn't so easy to replace in one shot, and it's still present in the system, transparently invoked by Quicktime X (or, for us developers, by QTKit) whenever it's needed.
But, how can a 64-bit software (like the Quicktime X Player, or the Finder itself) use a 32-bit library? The answer is, it doesn't, the technique used behind the scenes is far more interesting: when a 64-bit software needs a frame from a movie it can't process otherwise, a specific software is launched (you'll see it in the Activity Monitor as QTKitServer-(process-ID) process-name) that gives back the frames to the 64-bit app.
Hey, isn't that nice? Graphics passed from one process to another, how can they do that? The answer looks like it's in a new framework, IOSurface.

Disclaimer: the following statements are the result of personal experimentation: as such, they don't represent any official documentation nor endorsement.

IOSurface is included in the new public frameworks, but no mention of it exists in the official documentation: looking at the various C headers, however (not only in IOSurface.framework, but overall in the graphics libraries - Spotlight's your friend), it's possible to have a glimpse at its capabilities.

Putting together some sample code

A good example of how IOSurface works could be a quick and dirty implementation of a QTKitServer-lookalike, that plays any Quicktime movie in a 32-bit faceless application, and its 64-bit companion that shows the frames in an OpenGL view. More in detail, a IOSurface can be attached to many kinds of graphic surfaces and passed around to different tasks, that makes it the perfect candidate for our own version of a QTKitServer-clone. The link to the Xcode project is below - 10.6-only, of course.

The faceless movie player

Now, let's see how to create frames on IOSurfaces. For a start, we can create Core Video pixel buffers (one of the possibilities to define an offscreen destination for QT movies - see the excellent QTCoreVideo sample projects) that will have IOSurfaces bound to them: when we create the QTPixelBufferContext, introducing the proper items in the optional dictionary will instruct Core Video to attach IOSurfaces to each pixel buffer we'll get back. Each CVPixelBuffer we'll get from Core Video will then be asked for the related IOSurfaceRef: IOSurfaceRefs are the references to use inside the same application, and each surface has also a unique IOSurfaceID that can be referred to in other processes to obtain a local IOSurfaceRef.
For the sample I've put together, I've used the simplest way of passing IOSurfaces, i.e. asking them to be created global and passing around the IDs: not the ideal solution in the long term, but the other way (i.e. passing them through Mach ports) looks more complex and prone to errors to implement without the docs.
The small CLI app gets as the only argument the movie to play, and passes back the IDs of the surfaces through a simple pipe. Using the kIOSurfaceIsGlobal option puts also a limit in the consumer side: as the CLI doesn't know anything about the consumer, surfaces will be reused as soon as possible, so they'll have to be consumed at once. Binding them to Mach ports, however, would force the framework to create new surfaces until the previous ports are deallocated.

The 64-bit GUI application

Our 64-bit app is a very simple GUI: nothing really special here, a movie is chosen and passed to our faceless app launched in background as a NSTask, whose output is captured and parsed for IOSurfaceIDs. The interesting part is in the few lines that get the IOSurfaceID and build up a texture that we can use: the new call is CGLTexImageIOSurface2D, that is meant to be the IOSurface equivalent of glTexImage2D used in regular OpenGL to upload images.

Notes
The code is only good as a demo of the capabilities and for experimenting, in many aspects a real-world solution will use very different techniques!


Other posts on the same argument:

06 ottobre 2007

Citrix su Mac: ICA vs. RDP

Il confronto, stavolta, si fa ad armi (quasi) pari, e non è un caso: l'implementazione pratica di RDP sono i Terminal Services, presenti sulle versioni server di Windows a partire da NT 4, che hanno le loro radici proprio nella versione di allora (WinFrame) di quello che poi è diventato Presentation Server, come ho già illustrato. Nel tempo, gli sviluppi hanno mantenuto percorsi paralleli, con RDP normalmente un po' più indietro sia in termini di caratteristiche che capacità. Fino a RDP 5.2, che fa parte di Windows Server 2003, abbiamo quindi che entrambi:
  • Utilizzano un protocollo compatto ed ottimizzato sul sistema grafico Windows (GDI)
  • Permettono il reindirizzamento sul client remoto di una serie di device (disco, porte COM, stampanti, audio, clipboard), oltre naturalmente a quelli classici, ovvero schermo, tastiera e mouse

Con RDP 6, che però verrà effettivamente in uso solo con Windows Server 2008, incomincia ad apparire quello che invece fino ad ora erano state capacità esclusive di Presentation Server, ovvero:
  • Esecuzione in remoto di singole applicazioni, non di tutto il desktop
  • Solo la finestra dell'applicazione effettivamente "pubblicata" viene visualizzata sul client, non l'intero schermo, venendo quindi a tutti gli effetti ad integrarsi alle altre finestre dell'ambiente remoto (modalità Seamless, ripresa di recente sui Mac Intel anche in contesti simili, come ad esempio Parallels Desktop col nome Coherence e VMware Fusion con Unity)
  • Maggiore supporto per altri device remoti
  • Miglior gestione dei font
Le differenze, sulla carta, si riducono notevolmente: Presentation Server ha ancora molti vantaggi, come una migliore scalabilità, migliori ottimizzazioni su reti non veloci, e la possibilità (solo su Windows, ovviamente) di decidere di trasferire l'applicazione pubblicata sul client remoto per l'esecuzione, liberando risorse sul server.

Post precedenti:
Citrix su Mac: glossario
Citrix su Mac: un po' di storia
Citrix su Mac: ICA vs. VNC (e Apple Remote Desktop)
Citrix su Mac: ICA vs. X Windows

Citrix su Mac: ICA vs. X Windows

A prima vista, questo sembra uno strano confronto: cosa avranno mai a che fare un protocollo di comunicazione per applicazioni remote, tipicamente Windows, ed un sistema grafico normalmente usato su Unix?
In realtà, ci sono alcuni punti in comune: entrambi permettono la visualizzazione di un'applicazione su un display collegato ad una macchina separata, anche se in rete, rispetto a quella su cui l'applicazione stessa gira, con la relativa gestione e reindirizzamento degli eventi dalla postazione remota, ed entrambi utilizzano protocolli molto più compatti ed efficienti delle semplici bitmap (per quanto compresse ed ottimizzate) che sono alla base di VNC. Le similitudini finiscono qui, però: Presentation Server ha tutta una serie di caratteristiche avanzate, dal supporto di diversi canali di comunicazione fino alle varie ottimizzazioni del protocollo, che non trovano un corrispondente in X Windows. Per quello che riguarda esigenze semplici, in un ambiente prevalentemente Unix è certamente più efficace utilizzare X Windows rispetto a VNC, visto che i due hanno praticamente le stesse caratteristiche, mentre in un ambiente misto VNC ha il grosso vantaggio della più ampia gamma di sistemi operativi supportati, se si può ovviamente sorvolare sulle sue altre limitazioni.
Per completezza, riporto anche che esiste una versione di Presentation Server per Unix: rispetto al solo X Windows (sistema grafico su cui ovviamente si basa), può essere utile in quei casi in cui si debbano condividere più dello schermo, mouse e tastiera, o si abbia bisogno delle ottimizzazioni per reti lente che sono una delle caratteristiche più apprezzate di ICA.

Post precedenti:
Citrix su Mac: glossario
Citrix su Mac: un po' di storia
Citrix su Mac: ICA vs. VNC (e Apple Remote Desktop)

18 agosto 2007

Divagazione

Visto che avevo auspicato qualcosa del genere per Leopard, non posso che essere contento che, in qualche modo, la cosa stia accadendo ben più vicino al sottoscritto!
Certo, per ora non vuol dire assolutamente niente per OS X, considerando che Citrix è storicamente legata a Windows e il contributo diretto della piattaforma al fatturato è esattamente zero (esistono solo i client gratuiti), ma magari...

12 agosto 2007

Citrix su Mac: ICA vs. VNC (e Apple Remote Desktop)

Dopo le premesse, iniziamo quindi i confronti con tecnologie similari (e anche no): per essere precisi, comunque, il confronto in questa fase sarà prevalentemente tra i protocolli (e quindi si parla di ICA, nel caso di Citrix), piuttosto che sulle varie implementazioni che possono avere pregi e meriti di per sé, partendo da quello più ovvio e diffuso sulle varie piattaforme, ovvero VNC.
Come indicato nella pagina di illustrazione sul "come funziona", VNC, nei suoi concetti di base, è estremamente semplice da implementare, rendendolo ideale per essere il protocollo favorito nei progetti open source e multipiattaforma. "Posiziona questo gruppo di pixel alle coordinate X e Y" è il semplice fondamento della visualizzazione in remoto: sfortunatamente, dato che la banda è una risorsa limitata e preziosa, per avere un minimo di praticità deve essere usata una serie di algoritmi di compressione (anche diversi all'interno della stessa immagine). Proprio perché è stato pensato per l'assistenza remota e usi didattici, quello che l'utente remoto può fare non è molto, limitandosi tipicamente all'invio di input da mouse e tastiera: Apple, con la sua versione ARD, ha aggiunto funzioni utili all'aspetto amministrativo (come trasmissione di file, programmabilità via Automator, la funzione "Curtain" per prendere completamente il controllo della macchina, ...), ma ne ha mantenuto i concetti ed usi principali. Inoltre, nella sua forma fondamentale VNC permette solo di agire sullo schermo attivo in quel momento, vari utenti collegati vedono sempre lo stesso e solo uno può realisticamente controllare la macchina.

Per contro, ICA è nato proprio per esaltare la funzionalità di connessione permanente: l'applicazione (o le applicazioni, o anche tutto il desktop) che interessa rendere disponibile è installata su un server remoto per questioni di sicurezza e manutenzione (mantenere aggiornato e sicuro un solo server costa certamente di meno che fare lo stesso per ogni singolo client), e la separazione degli utenti è totale, ciascuno vede il suo schermo ed agisce sulla sua sessione in maniera indipendente. Di particolare interesse è anche il fatto che la grafica non è limitata a rettangoli di pixel, ma si adatta al contesto di utilizzo e, dove possibile, usa semplici e compatte primitive grafiche lasciando, ad esempio, al client funzioni relativamente avanzate quali la responsabilità del rendering del testo.
Il protocollo, invece di essere relativamente fisso come per VNC, utilizza il concetto di 'virtual channel', ovvero canali virtuali attraverso i quali possono viaggiare informazioni specifiche che il client vuole ottenere dal server, ciascuno operante nel formato più idoneo al tipo di dati che si vuole trasmettere.

Ad esempio, se ovviamente esistono canali dedicati a schermo, tastiera e mouse, esistono canali per file system (ovvero, un disco che appare come disponibile al server è in realtà locale per il client), per l'audio e il video, per le stampanti (permette di stampare su una stampante locale da un'applicazione remota), per le porte COM, e così via: le caratteristiche di ciascun canale vengono negoziate all'inizio della sessione, quindi è perfettamente possibile per un client non supportare un canale (o una parte delle sue capacità) e continuare con il collegamento. Inoltre, è possibile definire canali personalizzati (che devono essere ovviamente realizzati in concreto sia sul server che sul client).


Post precedenti:
Citrix su Mac: glossario
Citrix su Mac: un po' di storia

10 agosto 2007

Citrix su Mac: un po' di storia

L'accesso remoto su Mac non è cosa nuova, anzi! Si può andare indietro di circa 20 anni e trovare Timbuktu, usato specialmente per provvedere assistenza a distanza: date le linee dell'epoca, non si pretendeva un vero e proprio controllo in tempo reale, ma vedere cosa combinava l'utente dall'altra parte spesso era sufficiente a dare i consigli giusti per uscire da situazioni che, telefonicamente, sarebbero state impossibili da descrivere.
È invece intorno alla metà degli anni '90 che si assiste ad una evoluzione: da un lato troviamo i protocolli semplici come Timbuktu, basati sulla trasmissione di bitmap dal server, eventi dal client e poco di più, che trovano i loro successori in VNC (sviluppato originariamente nei laboratori inglesi della Olivetti) e tutti i suoi derivati, compreso Apple Remote Desktop, tuttora validi per collegamenti occasionali, particolarmente assistenza a distanza.
Ispirandosi invece più a X Windows, Citrix sviluppò, nello stesso periodo, WinFrame, ovvero una versione modificata di Windows NT 3.51 che dal mondo Unix mutuava il concetto di esecuzione remota di applicazioni con visualizzazione in locale: il concetto di base è profondamente differente, la connessione è progettata per essere permanente e non solo occasionale, e in rete transitano per lo più i comandi grafici, piuttosto che intere bitmap (anche se questo accade ugualmente, con tutte le ottimizzazioni del caso). Inoltre, il protocollo non riguarda solo la grafica, come vedremo, ma può essere, ed è, espanso per includere qualsiasi tipo di risorsa.
Nel 1997, con l'introduzione di Windows NT 4.0, Microsoft rileva il codice di WinFrame per farne la base di Terminal Services, mentre Citrix ne prosegue lo sviluppo in maniera indipendente, prima con MetaFrame e poi con l'attuale Presentation Server.
Parallelamente, Insignia (nota su Mac soprattutto per il suo SoftPC/SoftWindows) aveva sviluppato, sulla base WinFrame, NTrigue, ovvero un server che consentiva a terminali X Windows (e c'era una versione per Mac) di accedere ad applicazioni su Windows da remoto, espandendo quindi la base di possibili utenti client: Citrix rileva Insignia e la sua tecnologia all'inizio del 1998.