Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 4cab153c825c7ae3c886ef0c882ec95f1392adab 0 parents
@lu-zero authored
Showing with 650 additions and 0 deletions.
  1. +25 −0 COPYING
  2. +23 −0 Capture.h
  3. +534 −0 CaptureFFmpeg.cpp
  4. +36 −0 Makefile
  5. +32 −0 README
25 COPYING
@@ -0,0 +1,25 @@
+Copyright (c) 2009 Blackmagic Design
+Copyright (c) 2010 Luca Barbato
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
23 Capture.h
@@ -0,0 +1,23 @@
+#ifndef __CAPTURE_H__
+#define __CAPTURE_H__
+
+#include "DeckLinkAPI.h"
+
+class DeckLinkCaptureDelegate : public IDeckLinkInputCallback
+{
+public:
+ DeckLinkCaptureDelegate();
+ ~DeckLinkCaptureDelegate();
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+ virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags);
+ virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*);
+
+private:
+ ULONG m_refCount;
+ pthread_mutex_t m_mutex;
+};
+
+#endif
534 CaptureFFmpeg.cpp
@@ -0,0 +1,534 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+** Copyright (c) 2010 Luca Barbato
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "DeckLinkAPI.h"
+#include "Capture.h"
+extern "C" {
+#include "libavformat/avformat.h"
+}
+
+pthread_mutex_t sleepMutex;
+pthread_cond_t sleepCond;
+int videoOutputFile = -1;
+int audioOutputFile = -1;
+
+IDeckLink *deckLink;
+IDeckLinkInput *deckLinkInput;
+IDeckLinkDisplayModeIterator *displayModeIterator;
+IDeckLinkDisplayMode *displayMode;
+IDeckLinkConfiguration *deckLinkConfiguration;
+
+static int g_videoModeIndex = -1;
+static int g_audioChannels = 2;
+static int g_audioSampleDepth = 16;
+const char * g_videoOutputFile = NULL;
+const char * g_audioOutputFile = NULL;
+static int g_maxFrames = -1;
+
+static unsigned long frameCount = 0;
+
+AVFrame *picture;
+AVOutputFormat *fmt = NULL;
+AVFormatContext *oc;
+AVStream *audio_st, *video_st;
+BMDTimeValue frameRateDuration, frameRateScale;
+
+
+static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
+{
+ AVCodecContext *c;
+ AVCodec *codec;
+ AVStream *st;
+
+ st = av_new_stream(oc, 1);
+ if (!st) {
+ fprintf(stderr, "Could not alloc stream\n");
+ exit(1);
+ }
+
+ c = st->codec;
+ c->codec_id = codec_id;
+ c->codec_type = AVMEDIA_TYPE_AUDIO;
+
+ /* put sample parameters */
+ c->sample_fmt = SAMPLE_FMT_S16;
+// c->bit_rate = 64000;
+ c->sample_rate = 48000;
+ c->channels = 2;
+
+ // some formats want stream headers to be separate
+ if(oc->oformat->flags & AVFMT_GLOBALHEADER)
+ c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ codec = avcodec_find_encoder(c->codec_id);
+ if (!codec) {
+ fprintf(stderr, "codec not found\n");
+ exit(1);
+ }
+
+ if (avcodec_open(c, codec) < 0) {
+ fprintf(stderr, "could not open codec\n");
+ exit(1);
+ }
+
+ return st;
+}
+
+static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
+{
+ AVCodecContext *c;
+ AVCodec *codec;
+ AVStream *st;
+
+ st = av_new_stream(oc, 0);
+ if (!st) {
+ fprintf(stderr, "Could not alloc stream\n");
+ exit(1);
+ }
+
+ c = st->codec;
+ c->codec_id = codec_id;
+ c->codec_type = AVMEDIA_TYPE_VIDEO;
+
+ /* put sample parameters */
+// c->bit_rate = 400000;
+ /* resolution must be a multiple of two */
+ c->width = displayMode->GetWidth();
+ c->height = displayMode->GetHeight();
+ /* time base: this is the fundamental unit of time (in seconds) in terms
+ of which frame timestamps are represented. for fixed-fps content,
+ timebase should be 1/framerate and timestamp increments should be
+ identically 1.*/
+ displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
+ c->time_base.den = frameRateScale;
+ c->time_base.num = frameRateDuration;
+// c->gop_size = 12; /* emit one intra frame every twelve frames at most */
+ c->pix_fmt = PIX_FMT_UYVY422;
+
+ // some formats want stream headers to be separate
+ if(oc->oformat->flags & AVFMT_GLOBALHEADER)
+ c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ /* find the video encoder */
+ codec = avcodec_find_encoder(c->codec_id);
+ if (!codec) {
+ fprintf(stderr, "codec not found\n");
+ exit(1);
+ }
+
+ /* open the codec */
+ if (avcodec_open(c, codec) < 0) {
+ fprintf(stderr, "could not open codec\n");
+ exit(1);
+ }
+ picture = avcodec_alloc_frame();
+
+ return st;
+}
+
+DeckLinkCaptureDelegate::DeckLinkCaptureDelegate() : m_refCount(0)
+{
+ pthread_mutex_init(&m_mutex, NULL);
+}
+
+DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+ULONG DeckLinkCaptureDelegate::AddRef(void)
+{
+ pthread_mutex_lock(&m_mutex);
+ m_refCount++;
+ pthread_mutex_unlock(&m_mutex);
+
+ return (ULONG)m_refCount;
+}
+
+ULONG DeckLinkCaptureDelegate::Release(void)
+{
+ pthread_mutex_lock(&m_mutex);
+ m_refCount--;
+ pthread_mutex_unlock(&m_mutex);
+
+ if (m_refCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return (ULONG)m_refCount;
+}
+
+HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
+{
+ void *frameBytes;
+ void *audioFrameBytes;
+
+
+ // Handle Video Frame
+ if(videoFrame)
+ {
+ if (videoFrame->GetFlags() & bmdFrameHasNoInputSource)
+ {
+ fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount);
+ }
+ else
+ {
+ AVPacket pkt;
+ AVCodecContext *c;
+ av_init_packet(&pkt);
+ BMDTimeValue frameTime;
+ BMDTimeValue frameDuration;
+ c = video_st->codec;
+ //fprintf(stderr, "Frame received (#%lu) - Valid Frame (Size: %li bytes)\n", frameCount, videoFrame->GetRowBytes() * videoFrame->GetHeight());
+ videoFrame->GetBytes(&frameBytes);
+ avpicture_fill((AVPicture*)picture, (uint8_t *)frameBytes,
+ PIX_FMT_UYVY422,
+ videoFrame->GetWidth(), videoFrame->GetHeight());
+ videoFrame->GetStreamTime(&frameTime, &frameDuration, frameRateScale);
+// pkt.pts = pkt.dts = frameTime;
+ pkt.duration = frameDuration;
+ //To be made sure it still applies
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.stream_index= video_st->index;
+ pkt.data= (uint8_t *)frameBytes;
+ pkt.size= videoFrame->GetRowBytes() * videoFrame->GetHeight();
+ //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);
+ c->frame_number++;
+ av_interleaved_write_frame(oc, &pkt);
+ //write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
+ }
+ frameCount++;
+
+ if (g_maxFrames > 0 && frameCount >= g_maxFrames)
+ {
+ pthread_cond_signal(&sleepCond);
+ }
+ }
+
+ // Handle Audio Frame
+ if (audioFrame)
+ {
+ AVCodecContext *c;
+ AVPacket pkt;
+ BMDTimeValue audio_pts;
+ av_init_packet(&pkt);
+
+ c = audio_st->codec;
+ //hack among hacks
+ pkt.size = audioFrame->GetSampleFrameCount() *
+ g_audioChannels * (g_audioSampleDepth / 8);
+ audioFrame->GetBytes(&audioFrameBytes);
+ audioFrame->GetPacketTime(&audio_pts, frameRateScale);
+// pkt.dts = pkt.pts= audio_pts;
+ //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.stream_index= audio_st->index;
+ pkt.data = (uint8_t *)audioFrameBytes;
+// pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
+ c->frame_number++;
+ //write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels * (g_audioSampleDepth / 8));
+ if (av_interleaved_write_frame(oc, &pkt) != 0) {
+ fprintf(stderr, "Error while writing audio frame\n");
+ exit(1);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
+{
+ return S_OK;
+}
+
+int usage(int status)
+{
+ HRESULT result;
+ int displayModeCount = 0;
+
+ fprintf(stderr,
+ "Usage: Capture -m <mode id> [OPTIONS]\n"
+ "\n"
+ " -m <mode id>:\n"
+ );
+
+ while (displayModeIterator->Next(&displayMode) == S_OK)
+ {
+ char * displayModeString = NULL;
+
+ result = displayMode->GetName((const char **) &displayModeString);
+ if (result == S_OK)
+ {
+ BMDTimeValue frameRateDuration, frameRateScale;
+ displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
+ fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
+ displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration);
+ free(displayModeString);
+ displayModeCount++;
+ }
+
+ // Release the IDeckLinkDisplayMode object to prevent a leak
+ displayMode->Release();
+ }
+
+ fprintf(stderr,
+ " -f <filename> Filename raw video will be written to\n"
+ " -F <format> Define the file format to be used\n"
+ " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
+ " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
+ " -n <frames> Number of frames to capture (default is unlimited)\n"
+ "\n"
+ "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
+ "\n"
+ " Capture -m2 -n 50 -f video.raw -a audio.raw\n"
+ " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
+ );
+
+ exit(status);
+}
+
+int main(int argc, char *argv[])
+{
+ IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance();
+ DeckLinkCaptureDelegate *delegate;
+ BMDDisplayMode selectedDisplayMode = bmdModeNTSC;
+ int displayModeCount = 0;
+ int exitStatus = 1;
+ int connection = 0, camera = 0, i=0;
+ int ch;
+ HRESULT result;
+
+ pthread_mutex_init(&sleepMutex, NULL);
+ pthread_cond_init(&sleepCond, NULL);
+ av_register_all();
+
+ if (!deckLinkIterator)
+ {
+ fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
+ goto bail;
+ }
+ // Parse command line options
+ while ((ch = getopt(argc, argv, "?hc:s:f:a:m:n:F:C:I:")) != -1)
+ {
+ switch (ch)
+ {
+ case 'm':
+ g_videoModeIndex = atoi(optarg);
+ break;
+ case 'c':
+ g_audioChannels = atoi(optarg);
+ if (g_audioChannels != 2 &&
+ g_audioChannels != 8 &&
+ g_audioChannels != 16)
+ {
+ fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n");
+ goto bail;
+ }
+ break;
+ case 's':
+ g_audioSampleDepth = atoi(optarg);
+ if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32)
+ {
+ fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n");
+ goto bail;
+ }
+ break;
+ case 'f':
+ g_videoOutputFile = optarg;
+ break;
+ case 'n':
+ g_maxFrames = atoi(optarg);
+ break;
+ case 'F':
+ fmt = av_guess_format(optarg, NULL, NULL);
+ break;
+ case 'I':
+ connection = atoi(optarg);
+ break;
+ case 'C':
+ camera = atoi(optarg);
+ break;
+ case '?':
+ case 'h':
+ usage(0);
+ }
+ }
+
+ /* Connect to the first DeckLink instance */
+ do {
+ result = deckLinkIterator->Next(&deckLink);
+ } while(i++<camera);
+
+ if (result != S_OK)
+ {
+ fprintf(stderr, "No DeckLink PCI cards found.\n");
+ goto bail;
+ }
+
+ if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK)
+ goto bail;
+
+ result = deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration);
+ if (result != S_OK)
+ {
+ fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface - result = %08x\n", result);
+ goto bail;
+ }
+ //XXX make it generic
+ if (connection) {
+ deckLinkConfiguration->SetInt(bmdDeckLinkConfigVideoInputConnection,
+ bmdVideoConnectionComposite);
+ deckLinkConfiguration->SetInt(bmdDeckLinkConfigAudioInputConnection,
+ bmdAudioConnectionAnalog);
+ }
+ delegate = new DeckLinkCaptureDelegate();
+ deckLinkInput->SetCallback(delegate);
+
+ // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
+ result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
+ if (result != S_OK)
+ {
+ fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
+ goto bail;
+ }
+
+ if (!fmt)
+ fmt = av_guess_format(NULL, g_videoOutputFile, NULL);
+
+
+ if (g_videoModeIndex < 0)
+ {
+ fprintf(stderr, "No video mode specified\n");
+ usage(0);
+ }
+
+
+ selectedDisplayMode = -1;
+ while (displayModeIterator->Next(&displayMode) == S_OK)
+ {
+ if (g_videoModeIndex == displayModeCount)
+ {
+ selectedDisplayMode = displayMode->GetDisplayMode();
+ break;
+ }
+ displayModeCount++;
+ displayMode->Release();
+ }
+
+ oc = avformat_alloc_context();
+ oc->oformat = fmt;
+
+ snprintf(oc->filename, sizeof(oc->filename), "%s", g_videoOutputFile);
+
+ fmt->video_codec = CODEC_ID_RAWVIDEO;
+ fmt->audio_codec = CODEC_ID_PCM_S16LE;
+
+ video_st = add_video_stream(oc, fmt->video_codec);
+ audio_st = add_audio_stream(oc, fmt->audio_codec);
+
+ av_set_parameters(oc, NULL);
+
+ if (!(fmt->flags & AVFMT_NOFILE)) {
+ if (url_fopen(&oc->pb, oc->filename, URL_WRONLY) < 0) {
+ fprintf(stderr, "Could not open '%s'\n", oc->filename);
+ exit(1);
+ }
+ }
+
+ if (selectedDisplayMode < 0)
+ {
+ fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex);
+ goto bail;
+ }
+
+ result = deckLinkInput->EnableVideoInput(selectedDisplayMode, bmdFormat8BitYUV, 0);
+ if(result != S_OK)
+ {
+ fprintf(stderr, "Failed to enable video input. Is another application using the card?\n");
+ goto bail;
+ }
+
+ result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
+ if(result != S_OK)
+ {
+ goto bail;
+ }
+ av_write_header(oc);
+
+ result = deckLinkInput->StartStreams();
+ if(result != S_OK)
+ {
+ goto bail;
+ }
+ // All Okay.
+ exitStatus = 0;
+
+ // Block main thread until signal occurs
+ pthread_mutex_lock(&sleepMutex);
+ pthread_cond_wait(&sleepCond, &sleepMutex);
+ pthread_mutex_unlock(&sleepMutex);
+ fprintf(stderr, "Stopping Capture\n");
+
+bail:
+ if (displayModeIterator != NULL)
+ {
+ displayModeIterator->Release();
+ displayModeIterator = NULL;
+ }
+
+ if (deckLinkInput != NULL)
+ {
+ deckLinkInput->Release();
+ deckLinkInput = NULL;
+ }
+
+ if (deckLink != NULL)
+ {
+ deckLink->Release();
+ deckLink = NULL;
+ }
+
+ if (deckLinkIterator != NULL)
+ deckLinkIterator->Release();
+
+ av_write_trailer(oc);
+ if (!(fmt->flags & AVFMT_NOFILE)) {
+ /* close the output file */
+ url_fclose(oc->pb);
+ }
+
+ return exitStatus;
+}
+
36 Makefile
@@ -0,0 +1,36 @@
+#** -LICENSE-START-
+#** Copyright (c) 2009 Blackmagic Design
+#**
+#** Permission is hereby granted, free of charge, to any person or organization
+#** obtaining a copy of the software and accompanying documentation covered by
+#** this license (the "Software") to use, reproduce, display, distribute,
+#** execute, and transmit the Software, and to prepare derivative works of the
+#** Software, and to permit third-parties to whom the Software is furnished to
+#** do so, all subject to the following:
+#**
+#** The copyright notices in the Software and this entire statement, including
+#** the above license grant, this restriction and the following disclaimer,
+#** must be included in all copies of the Software, in whole or in part, and
+#** all derivative works of the Software, unless such copies or derivative
+#** works are solely in the form of machine-executable object code generated by
+#** a source language processor.
+#**
+#** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+#** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+#** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+#** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#** DEALINGS IN THE SOFTWARE.
+#** -LICENSE-END-
+
+CC=g++
+SDK_PATH=../../include
+CFLAGS=-Wno-multichar -I $(SDK_PATH) -fno-rtti -D__STDC_CONSTANT_MACROS -g
+LDFLAGS=-lm -ldl -lpthread `pkg-config --libs libavformat`
+
+CaptureFFmpeg: CaptureFFmpeg.cpp $(SDK_PATH)/DeckLinkAPIDispatch.cpp
+ $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
+
+clean:
+ rm -f CaptureFFmpeg
32 README
@@ -0,0 +1,32 @@
+
+ -- What is it?
+
+This is a quite simple A/V capture based on ffmpeg for Blackmagic Design
+DeckLink systems.
+
+It isn't exactly feature complete and had been used as testbed to develop
+a crude avdevice for ffmpeg and then kept around since it comes handy in many
+occasions since the avdevice has it's share of issues I don't have time nor
+will to debug given I don't own a decklink card myself.
+
+ -- How to build?
+
+In order to build it just clone/unpack this on your Sample directory from the
+DeckLink SDK and then issue "make". If you have ffmpeg and pkg-config installed
+it will build fine
+
+ -- How to use?
+
+./CaptureFFmpeg -C 1 -m 2 -I 1 -F nut -f pipe:1 | ffmpeg -y -i - <your options here>
+
+-I switch from the default (HDMI) source to Analog (both audio and video)
+
+-C select the capture device if more than one is present.
+
+-F define the container format, I suggest using nut.
+
+-f output file name, any libavformat compatible url is supported.
+
+ -- Contact
+
+You can contact me either at lu_zero@gentoo.org or luca.barbato@axant.it
Please sign in to comment.
Something went wrong with that request. Please try again.