function VideoDVCamCaptureDemo(fullscreen, fullsize, roi, depth, deviceId, moviename) % Demonstrate simple use of built-in video capture engine with DV consumer cameras. % % VideoDVCamCaptureDemo([fullscreen=0][, fullsize=0][, roi][, depth][,deviceId=0][, moviename]) % % NOTE: As of October 2014, DV video camera capture has not been tested at % all on MS-Windows, as GStreamer-1 currently doesn't ship with video % capture plugins for MS-Windows. On Apple OSX 10.9.5 Mavericks with our % new GStreamer-1 video capture engine, video capture from DV did not work, % neither with Psychtoolbox, nor with GStreamer command line tools or other % independent open source video capture applications. Only Apples Facetime % app managed to get a marginally useable video stream from the DV camera. % Testing on Linux with this specific demo showed mixed results. However on % Linux there is a slightly hacky way that makes it work somewhat reliably % with the new backend by exposing the camera as a regular video source, so % all regular video capture/recording/processing demos can be used for DV % capture, without any need for special treatment like in this demo. Read % the section below for further instructions for a reliable DV setup on % Linux. % % VideoDVCamCaptureDemo initializes the first attached and supported DV % firewire consumer camera, then shows its video image in a Psychtoolbox % window. A press of the ESCape key ends the demo. % % Optional parameters: % % 'fullscreen' If set to non-zero value, the image is displayed in a % fullscreen window, as usual, otherwise a normal GUI window is used. % % 'fullsize' If set to 1, the cameras image is scaled up to full screen % resolution, ie. so it fills the maximum amount of display area, but % preserving the original aspect ratio. % % 'roi' Set to [0 0 720 576] for a PAL-DV camera and [0 0 720 480] for a % NTSC-DV camera. Default is PAL if omitted. % % 'deviceId' Device index of video capture device. Defaults to system % default. You can also specify a gst-launch style string to define a % videosource here. Or you can set the special string deviceId = 'X' so % builtin spec strings suitable for each operating system will be used. % % 'moviename' Name string for selection of filename of a target movie file % to which video should be recorded. Defaults to none,ie., no video % recording. % % VideoDVCamCaptureDemo also allows you to test out video capture from % special video sources other than Consumer-DV cameras, ie. sources which % require use of a custom built GStreamer video source bin. You test such % setups by specifying the bin spec-string and other parameters as parameters % for the demo. As an example, the following call would try to capture a video % stream that is encoded as H264 video and that is transmitted over the network % via TCP-IP protocol, ie., a H264 video stream encapsulated in TCP: % % VideoDVCamCaptureDemo([], [], [0 0 320 240], 6, 'tcpclientsrc port=8554 host=localhost ! h264parse ! avdec_h264 name=ptbdvsource'); % % This would receive the TCP stream from port 8554 on the machine with % the name 'localhost' (the local machine). The stream would decode from % H264 to color format 6 - YUV-I420 - with video frames of 320 x 240 pixels % size. For testing purpose you could enter the following GStreamer command % line into a terminal window to generate a test video stream and send it from % the local machine 'localhost' on port 8554, as H264 encoded TCP-IP stream, % then receive it via VideoDVCamCaptureDemo as shown above: % % gst-launch-1.0 videotestsrc horizontal-speed=5 ! x264enc tune="zerolatency" threads=1 ! video/x-h264,stream-format=byte-stream ! tcpserversink port=8554 % % One application of such a custom setup can be seen in the discussion thread % containing message #18807 on the Psychtoolbox forum. There the video source % is an IP camera attached to a robot, streaming H264 video over the network for % consumption by a machine running Psychtoolbox. % % % % % Loopback setup on Linux for use with new GStreamer-1 video backend: % % This specific configuration was shown to work at least on Ubuntu 14.04 % LTS with a Sony PAL-DV firewire camera. After following the setup steps, % demos like our standard VideoCaptureDemo, VideoRecordingDemo, ... worked % without any special configuration or treatment of DV cameras. % % Here you need to install a Video4Linux2 loopback kernel module. It will % allow to create virtual video sources, from which Psychtoolbox can % read/capture/process record live video. Then some external application % can feed video into those virtual sources. You then attach an external % command line DV capture session as video source. % % 1. Install the package "v4l2loopback-dkms" to get the kernel module installed and % loaded. A "sudo apt-get install v4l2loopback-dkms" on Ubuntu 14.04-LTS % and later distributions should do the trick. The package is probably % also available on Debian, other Debian/Ubuntu derived distros etc. Or % you get the most recent version to compile and install from source % code from the homepage of the project: % https://github.com/umlaeute/v4l2loopback % % 2. You may or may not need to "sudo modprobe v4l2loopback" on first use. % % 3. Then you use a GStreamer video capture pipeline launched from a terminal % window to connect to your DV camera, capture live video and feed it % into the virtual video loopback device. An example launch line can % look like this: % % gst-launch dv1394src ! dvdemux ! dvdec ! v4l2sink device=/dev/video0 % % This would make live video from the first connected DV camera % available on /dev/video0. See % https://github.com/umlaeute/v4l2loopback/wiki for more detailed % instructions. % % If this doesn't work for you with GStreamer-1 you may need to install % good old GStreamer-0.10 in addition to the already installed % GStreamer-1 and instead use the gst-launch-0.10 command instead of the % gst-launch command to select for the old implementation. % % 4. Psychtoolbox video capture functions should now report and be able to % use a new virtual video capture device with a name like "Dummy video % device 0000" or some name defined by you. Psychtoolbox should be able % to video capture or record video from that device aka your DV video % camera. % % The Wiki of v4l2loopback describes more elaborate setups, e.g., for % capturing from multiple video DV cameras. % % History: % 27-Dec-2013 mk Written. % 26-Aug-2014 mk Adapted to GStreamer-1.4.0+ backend. % 19-Sep-2014 mk Update instructions for GStreamer-1.x, drop dead code for GStreamer-1. % 05-Oct-2014 mk Clarify OSX doesn't work at all. Deuglify help text formatting a bit. % 02-Mar-2015 mk Add example use case "video streaming over TCP network" to help text. PsychDefaultSetup(1); if nargin < 1 fullscreen=[]; end if isempty(fullscreen) fullscreen=0; end if nargin < 2 fullsize=[]; end if isempty(fullsize) fullsize=0; end if nargin < 3 || isempty(roi) % Must set explicit roi with video resolution. Only two options, % 720 x 576 for PAL DV cameras, and 720 x 480 for NTSC DV cameras. % We choose PAL: roi = [0 0 720 576]; end if nargin < 4 depth = []; end if nargin < 5 deviceId = []; end if nargin < 6 moviename = []; end recordingflags = 0; screenid=max(Screen('Screens')); try if fullscreen<1 win=Screen('OpenWindow', screenid, 0, [0 0 800 600]); else win=Screen('OpenWindow', screenid, 0); end; % Initial flip to a blank screen: Screen('Flip',win); % Set text size for info text to 24 pixels. Screen('TextSize', win, 24); % Use of a gst-launch style spec for a video source requested? A deviceId which % is actually a character string would signal this: if ischar(deviceId) % Yes. Meaningful spec string, or only a single dummy character? if length(deviceId) < 2 % Dummy: Replace by hard-coded "known to work" example string: if IsLinux % Any of these work on Linux: capturebinspec = 'dv1394src ! dvdemux ! dvdec name=ptbdvsource'; %capturebinspec = 'dv1394src ! video/x-dv ! dvdemux ! dvdec name=ptbdvsource'; %capturebinspec = 'dv1394src ! dvdemux ! avdec_dvvideo name=ptbdvsource'; end if IsWin % This should work on MS-Windows, as tested with a Sony PAL-DV camera: capturebinspec = 'dshowvideosrc ! dvdemux ! avdec_dvvideo name=ptbdvsource'; if Is64Bit warning('To our knowledge (as of August 2014, GStreamer-1.4.0) video capture is not yet\nsupported on MS-Windows, so this will likely fail.\n'); end end if IsOSX % This should work on OSX, if at all. If this doesn't work then game-over (Untested): warning('To our knowledge (as of October 2014, GStreamer-1.4.0) video capture from DV cameras on OSX does not work correctly, so this will likely fail.\n'); capturebinspec = 'avfvideosrc name=ptbdvsource'; end else % Real string: Use it. capturebinspec = deviceId; end if isempty(roi) error('You *must* specify a roi of [0 0 720 576] for PAL-DV or [0 0 720 480] for NTSC-DV if you define your own video capture source via deviceId as a string!'); end % Assign capturebinspec as gst-launch style capture bin spec for use as video source: Screen('SetVideoCaptureParameter', -1, sprintf('SetNextCaptureBinSpec=%s', capturebinspec)); % Signal to Screen() that spec string should be used. This via special deviceId -9: deviceId = -9; end % Open DV camera: We always use engineId 3 for GStreamer, as only GStreamer supports DV cameras atm.: grabber = Screen('OpenVideoCapture', win, deviceId, roi, depth, [], [], moviename, recordingflags, 3); % We refrain from setting target fps here, as DV cameras do have a fixed fps. Instead % we use the "do what you think is right" 'realmax' joker. Screen('StartVideoCapture', grabber, realmax, 1); dstRect = []; oldpts = 0; count = 0; t=GetSecs; % Run for at most 600 seconds or until keypress: while (GetSecs - t) < 600 if KbCheck(-1) break; end [tex pts nrdropped,intensity]=Screen('GetCapturedImage', win, grabber, 1); %#ok % fprintf('tex = %i pts = %f nrdropped = %i\n', tex, pts, nrdropped); if tex > 0 % Perform first-time setup of transformations, if needed: if fullsize && (count == 0) texrect = Screen('Rect', tex); winrect = Screen('Rect', win); sf = min([RectWidth(winrect) / RectWidth(texrect) , RectHeight(winrect) / RectHeight(texrect)]); dstRect = CenterRect(ScaleRect(texrect, sf, sf) , winrect); end % texinfo = Screen('Getwindowinfo', tex) % outintens = intensity % Draw new texture from framegrabber. Screen('DrawTexture', win, tex, [], dstRect); % Print pts: Screen('DrawText', win, sprintf('%.4f', pts), 0, 0, 255); if count > 0 % Compute delta: delta = (pts - oldpts) * 1000; oldpts = pts; Screen('DrawText', win, sprintf('%.4f', delta), 0, 20, 255); end % Show it. Screen('Flip', win); Screen('Close', tex); end count = count + 1; end telapsed = GetSecs - t %#ok Screen('StopVideoCapture', grabber); Screen('CloseVideoCapture', grabber); sca; avgfps = count / telapsed %#ok catch %#ok sca; end