decklink: reindent

This commit is contained in:
David Schleef 2011-06-05 21:17:04 -07:00
parent ca8ea19cc3
commit 1e1c16150b
4 changed files with 294 additions and 244 deletions

View File

@ -34,9 +34,10 @@
#define kDeckLinkAPI_Name "libDeckLinkAPI.so" #define kDeckLinkAPI_Name "libDeckLinkAPI.so"
#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" #define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so"
typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); typedef IDeckLinkIterator *(*CreateIteratorFunc) (void);
typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); typedef IDeckLinkGLScreenPreviewHelper
typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); * (*CreateOpenGLScreenPreviewHelperFunc) (void);
typedef IDeckLinkVideoConversion *(*CreateVideoConversionInstanceFunc) (void);
static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT;
static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT;
@ -45,66 +46,72 @@ static CreateIteratorFunc gCreateIteratorFunc = NULL;
static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL;
static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL;
static static void
void InitDeckLinkAPI (void) InitDeckLinkAPI (void)
{ {
void *libraryHandle; void *libraryHandle;
libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); libraryHandle = dlopen (kDeckLinkAPI_Name, RTLD_NOW | RTLD_GLOBAL);
if (!libraryHandle) if (!libraryHandle) {
{ fprintf (stderr, "%s\n", dlerror ());
fprintf(stderr, "%s\n", dlerror());
return; return;
} }
gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0001"); gCreateIteratorFunc =
(CreateIteratorFunc) dlsym (libraryHandle,
"CreateDeckLinkIteratorInstance_0001");
if (!gCreateIteratorFunc) if (!gCreateIteratorFunc)
fprintf(stderr, "%s\n", dlerror()); fprintf (stderr, "%s\n", dlerror ());
gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); gCreateVideoConversionFunc =
(CreateVideoConversionInstanceFunc) dlsym (libraryHandle,
"CreateVideoConversionInstance_0001");
if (!gCreateVideoConversionFunc) if (!gCreateVideoConversionFunc)
fprintf(stderr, "%s\n", dlerror()); fprintf (stderr, "%s\n", dlerror ());
} }
static static void
void InitDeckLinkPreviewAPI (void) InitDeckLinkPreviewAPI (void)
{ {
void *libraryHandle; void *libraryHandle;
libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); libraryHandle = dlopen (KDeckLinkPreviewAPI_Name, RTLD_NOW | RTLD_GLOBAL);
if (!libraryHandle) if (!libraryHandle) {
{ fprintf (stderr, "%s\n", dlerror ());
fprintf(stderr, "%s\n", dlerror());
return; return;
} }
gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); gCreateOpenGLPreviewFunc =
(CreateOpenGLScreenPreviewHelperFunc) dlsym (libraryHandle,
"CreateOpenGLScreenPreviewHelper_0001");
if (!gCreateOpenGLPreviewFunc) if (!gCreateOpenGLPreviewFunc)
fprintf(stderr, "%s\n", dlerror()); fprintf (stderr, "%s\n", dlerror ());
} }
IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) IDeckLinkIterator *
CreateDeckLinkIteratorInstance (void)
{ {
pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); pthread_once (&gDeckLinkOnceControl, InitDeckLinkAPI);
if (gCreateIteratorFunc == NULL) if (gCreateIteratorFunc == NULL)
return NULL; return NULL;
return gCreateIteratorFunc(); return gCreateIteratorFunc ();
} }
IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) IDeckLinkGLScreenPreviewHelper *
CreateOpenGLScreenPreviewHelper (void)
{ {
pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); pthread_once (&gDeckLinkOnceControl, InitDeckLinkAPI);
pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); pthread_once (&gPreviewOnceControl, InitDeckLinkPreviewAPI);
if (gCreateOpenGLPreviewFunc == NULL) if (gCreateOpenGLPreviewFunc == NULL)
return NULL; return NULL;
return gCreateOpenGLPreviewFunc(); return gCreateOpenGLPreviewFunc ();
} }
IDeckLinkVideoConversion* CreateVideoConversionInstance (void) IDeckLinkVideoConversion *
CreateVideoConversionInstance (void)
{ {
pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); pthread_once (&gDeckLinkOnceControl, InitDeckLinkAPI);
if (gCreateVideoConversionFunc == NULL) if (gCreateVideoConversionFunc == NULL)
return NULL; return NULL;
return gCreateVideoConversionFunc(); return gCreateVideoConversionFunc ();
} }

View File

@ -83,7 +83,7 @@ DeckLinkCaptureDelegate::Release (void)
} }
HRESULT HRESULT
DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame * DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame *
videoFrame, IDeckLinkAudioInputPacket * audioFrame) videoFrame, IDeckLinkAudioInputPacket * audioFrame)
{ {
GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (priv); GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (priv);
@ -91,7 +91,7 @@ DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame *
// Handle Video Frame // Handle Video Frame
if (videoFrame) { if (videoFrame) {
if (videoFrame->GetFlags () & bmdFrameHasNoInputSource) { if (videoFrame->GetFlags () & bmdFrameHasNoInputSource) {
GST_DEBUG("Frame received - No input signal detected"); GST_DEBUG ("Frame received - No input signal detected");
} else { } else {
const char *timecodeString = NULL; const char *timecodeString = NULL;
if (g_timecodeFormat != 0) { if (g_timecodeFormat != 0) {
@ -101,10 +101,9 @@ DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame *
} }
} }
GST_DEBUG("Frame received [%s] - %s - Size: %li bytes", GST_DEBUG ("Frame received [%s] - %s - Size: %li bytes",
timecodeString != NULL ? timecodeString : "No timecode", timecodeString != NULL ? timecodeString : "No timecode",
"Valid Frame", "Valid Frame", videoFrame->GetRowBytes () * videoFrame->GetHeight ());
videoFrame->GetRowBytes () * videoFrame->GetHeight ());
if (timecodeString) if (timecodeString)
free ((void *) timecodeString); free ((void *) timecodeString);
@ -113,10 +112,10 @@ DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame *
if (decklinksrc->video_frame != NULL) { if (decklinksrc->video_frame != NULL) {
decklinksrc->dropped_frames++; decklinksrc->dropped_frames++;
} else { } else {
videoFrame->AddRef(); videoFrame->AddRef ();
decklinksrc->video_frame = videoFrame; decklinksrc->video_frame = videoFrame;
if (audioFrame) { if (audioFrame) {
audioFrame->AddRef(); audioFrame->AddRef ();
decklinksrc->audio_frame = audioFrame; decklinksrc->audio_frame = audioFrame;
} }
} }
@ -128,11 +127,10 @@ DeckLinkCaptureDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame *
} }
HRESULT HRESULT
DeckLinkCaptureDelegate:: DeckLinkCaptureDelegate::VideoInputFormatChanged
VideoInputFormatChanged (BMDVideoInputFormatChangedEvents events, (BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode * mode,
IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags) BMDDetectedVideoInputFormatFlags) {
{ GST_ERROR ("moo");
GST_ERROR("moo");
return S_OK; return S_OK;
} }
@ -140,19 +138,25 @@ VideoInputFormatChanged (BMDVideoInputFormatChangedEvents events,
int int
usage (int status) usage (int status)
{ {
HRESULT result; HRESULT
IDeckLinkDisplayMode *displayMode; result;
int displayModeCount = 0; IDeckLinkDisplayMode *
displayMode;
int
displayModeCount = 0;
fprintf (stderr, fprintf (stderr,
"Usage: Capture -m <mode id> [OPTIONS]\n" "\n" " -m <mode id>:\n"); "Usage: Capture -m <mode id> [OPTIONS]\n" "\n" " -m <mode id>:\n");
while (displayModeIterator->Next (&displayMode) == S_OK) { while (displayModeIterator->Next (&displayMode) == S_OK) {
char *displayModeString = NULL; char *
displayModeString = NULL;
result = displayMode->GetName ((const char **) &displayModeString); result = displayMode->GetName ((const char **) &displayModeString);
if (result == S_OK) { if (result == S_OK) {
BMDTimeValue frameRateDuration, frameRateScale; BMDTimeValue
frameRateDuration,
frameRateScale;
displayMode->GetFrameRate (&frameRateDuration, &frameRateScale); displayMode->GetFrameRate (&frameRateDuration, &frameRateScale);
fprintf (stderr, " %2d: %-20s \t %li x %li \t %g FPS\n", fprintf (stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
@ -194,17 +198,28 @@ usage (int status)
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance (); IDeckLinkIterator *
DeckLinkCaptureDelegate *delegate; deckLinkIterator = CreateDeckLinkIteratorInstance ();
IDeckLinkDisplayMode *displayMode; DeckLinkCaptureDelegate *
BMDVideoInputFlags inputFlags = 0; delegate;
BMDDisplayMode selectedDisplayMode = bmdModeNTSC; IDeckLinkDisplayMode *
BMDPixelFormat pixelFormat = bmdFormat8BitYUV; displayMode;
int displayModeCount = 0; BMDVideoInputFlags
int exitStatus = 1; inputFlags = 0;
int ch; BMDDisplayMode
bool foundDisplayMode = false; selectedDisplayMode = bmdModeNTSC;
HRESULT result; BMDPixelFormat
pixelFormat = bmdFormat8BitYUV;
int
displayModeCount = 0;
int
exitStatus = 1;
int
ch;
bool
foundDisplayMode = false;
HRESULT
result;
pthread_mutex_init (&sleepMutex, NULL); pthread_mutex_init (&sleepMutex, NULL);
pthread_cond_init (&sleepCond, NULL); pthread_cond_init (&sleepCond, NULL);
@ -334,8 +349,10 @@ main (int argc, char *argv[])
while (displayModeIterator->Next (&displayMode) == S_OK) { while (displayModeIterator->Next (&displayMode) == S_OK) {
if (g_videoModeIndex == displayModeCount) { if (g_videoModeIndex == displayModeCount) {
BMDDisplayModeSupport result; BMDDisplayModeSupport
const char *displayModeName; result;
const char *
displayModeName;
foundDisplayMode = true; foundDisplayMode = true;
displayMode->GetName (&displayModeName); displayMode->GetName (&displayModeName);
@ -427,4 +444,3 @@ bail:
return exitStatus; return exitStatus;
} }
#endif #endif

View File

@ -67,7 +67,8 @@ static gboolean gst_decklink_sink_query (GstElement * element,
GstQuery * query); GstQuery * query);
static GstCaps *gst_decklink_sink_videosink_getcaps (GstPad * pad); static GstCaps *gst_decklink_sink_videosink_getcaps (GstPad * pad);
static gboolean gst_decklink_sink_videosink_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_sink_videosink_setcaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_decklink_sink_videosink_acceptcaps (GstPad * pad, static gboolean gst_decklink_sink_videosink_acceptcaps (GstPad * pad,
GstCaps * caps); GstCaps * caps);
static gboolean gst_decklink_sink_videosink_activate (GstPad * pad); static gboolean gst_decklink_sink_videosink_activate (GstPad * pad);
@ -81,15 +82,18 @@ static GstFlowReturn gst_decklink_sink_videosink_chain (GstPad * pad,
GstBuffer * buffer); GstBuffer * buffer);
static GstFlowReturn gst_decklink_sink_videosink_chainlist (GstPad * pad, static GstFlowReturn gst_decklink_sink_videosink_chainlist (GstPad * pad,
GstBufferList * bufferlist); GstBufferList * bufferlist);
static gboolean gst_decklink_sink_videosink_event (GstPad * pad, GstEvent * event); static gboolean gst_decklink_sink_videosink_event (GstPad * pad,
static gboolean gst_decklink_sink_videosink_query (GstPad * pad, GstQuery * query); GstEvent * event);
static gboolean gst_decklink_sink_videosink_query (GstPad * pad,
GstQuery * query);
static GstFlowReturn gst_decklink_sink_videosink_bufferalloc (GstPad * pad, static GstFlowReturn gst_decklink_sink_videosink_bufferalloc (GstPad * pad,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static GstIterator *gst_decklink_sink_videosink_iterintlink (GstPad * pad); static GstIterator *gst_decklink_sink_videosink_iterintlink (GstPad * pad);
static GstCaps *gst_decklink_sink_audiosink_getcaps (GstPad * pad); static GstCaps *gst_decklink_sink_audiosink_getcaps (GstPad * pad);
static gboolean gst_decklink_sink_audiosink_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_sink_audiosink_setcaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_decklink_sink_audiosink_acceptcaps (GstPad * pad, static gboolean gst_decklink_sink_audiosink_acceptcaps (GstPad * pad,
GstCaps * caps); GstCaps * caps);
static gboolean gst_decklink_sink_audiosink_activate (GstPad * pad); static gboolean gst_decklink_sink_audiosink_activate (GstPad * pad);
@ -103,8 +107,10 @@ static GstFlowReturn gst_decklink_sink_audiosink_chain (GstPad * pad,
GstBuffer * buffer); GstBuffer * buffer);
static GstFlowReturn gst_decklink_sink_audiosink_chainlist (GstPad * pad, static GstFlowReturn gst_decklink_sink_audiosink_chainlist (GstPad * pad,
GstBufferList * bufferlist); GstBufferList * bufferlist);
static gboolean gst_decklink_sink_audiosink_event (GstPad * pad, GstEvent * event); static gboolean gst_decklink_sink_audiosink_event (GstPad * pad,
static gboolean gst_decklink_sink_audiosink_query (GstPad * pad, GstQuery * query); GstEvent * event);
static gboolean gst_decklink_sink_audiosink_query (GstPad * pad,
GstQuery * query);
static GstFlowReturn gst_decklink_sink_audiosink_bufferalloc (GstPad * pad, static GstFlowReturn gst_decklink_sink_audiosink_bufferalloc (GstPad * pad,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static GstIterator *gst_decklink_sink_audiosink_iterintlink (GstPad * pad); static GstIterator *gst_decklink_sink_audiosink_iterintlink (GstPad * pad);
@ -125,58 +131,68 @@ static GstStaticPadTemplate gst_decklink_sink_videosink_template =
GST_STATIC_PAD_TEMPLATE ("videosink", GST_STATIC_PAD_TEMPLATE ("videosink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ( GST_STATIC_CAPS (MODE (720, 486, 30000, 1001, true)
MODE(720,486,30000,1001,true)
)); ));
#if 0 #if 0
MODE(720,486,24000,1001,true) ";" MODE (720, 486, 24000, 1001, true) ";"
MODE(720,576,25,1,true) ";" MODE (720, 576, 25, 1, true)
MODE(1920,1080,24000,1001,false) ";" ";"
MODE(1920,1080,24,1,false) ";" MODE (1920, 1080, 24000, 1001, false)
MODE(1920,1080,25,1,false) ";" ";"
MODE(1920,1080,30000,1001,false) ";" MODE (1920, 1080, 24, 1, false)
MODE(1920,1080,30,1,false) ";" ";"
MODE(1920,1080,25,1,true) ";" MODE (1920, 1080, 25, 1, false)
MODE(1920,1080,30000,1001,true) ";" ";"
MODE(1920,1080,30,1,true) ";" MODE (1920, 1080, 30000, 1001, false)
MODE(1280,720,50,1,true) ";" ";"
MODE(1280,720,60000,1001,true) ";" MODE (1920, 1080, 30, 1, false)
MODE(1280,720,60,1,true) ";"
MODE (1920, 1080, 25, 1, true)
";"
MODE (1920, 1080, 30000, 1001, true)
";"
MODE (1920, 1080, 30, 1, true)
";"
MODE (1280, 720, 50, 1, true)
";"
MODE (1280, 720, 60000, 1001, true)
";"
MODE (1280, 720, 60, 1, true)
#endif #endif
static GstStaticPadTemplate gst_decklink_sink_audiosink_template =
static GstStaticPadTemplate gst_decklink_sink_audiosink_template = GST_STATIC_PAD_TEMPLATE ("audiosink",
GST_STATIC_PAD_TEMPLATE ("audiosink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int,width=16,depth=16,channels=2,rate=48000") GST_STATIC_CAPS ("audio/x-raw-int,width=16,depth=16,channels=2,rate=48000")
); );
typedef struct _DecklinkMode DecklinkMode; typedef struct _DecklinkMode DecklinkMode;
struct _DecklinkMode { struct _DecklinkMode
{
BMDDisplayMode mode; BMDDisplayMode mode;
int width; int width;
int height; int height;
int fps_n; int fps_n;
int fps_d; int fps_d;
gboolean interlaced; gboolean interlaced;
}; };
static DecklinkMode modes[] = { static DecklinkMode modes[] = {
{ bmdModeNTSC, 720,486,30000,1001,true }, {bmdModeNTSC, 720, 486, 30000, 1001, true},
{ bmdModeNTSC2398, 720,486,24000,1001,true }, {bmdModeNTSC2398, 720, 486, 24000, 1001, true},
{ bmdModePAL, 720,576,25,1,true }, {bmdModePAL, 720, 576, 25, 1, true},
{ bmdModeHD1080p2398, 1920,1080,24000,1001,false }, {bmdModeHD1080p2398, 1920, 1080, 24000, 1001, false},
{ bmdModeHD1080p24, 1920,1080,24,1,false }, {bmdModeHD1080p24, 1920, 1080, 24, 1, false},
{ bmdModeHD1080p25, 1920,1080,25,1,false }, {bmdModeHD1080p25, 1920, 1080, 25, 1, false},
{ bmdModeHD1080p2997, 1920,1080,30000,1001,false }, {bmdModeHD1080p2997, 1920, 1080, 30000, 1001, false},
{ bmdModeHD1080p30, 1920,1080,30,1,false }, {bmdModeHD1080p30, 1920, 1080, 30, 1, false},
{ bmdModeHD1080i50, 1920,1080,25,1,true }, {bmdModeHD1080i50, 1920, 1080, 25, 1, true},
{ bmdModeHD1080i5994, 1920,1080,30000,1001,true }, {bmdModeHD1080i5994, 1920, 1080, 30000, 1001, true},
{ bmdModeHD1080i6000, 1920,1080,30,1,true }, {bmdModeHD1080i6000, 1920, 1080, 30, 1, true},
{ bmdModeHD720p50, 1280,720,50,1,true }, {bmdModeHD720p50, 1280, 720, 50, 1, true},
{ bmdModeHD720p5994, 1280,720,60000,1001,true }, {bmdModeHD720p5994, 1280, 720, 60000, 1001, true},
{ bmdModeHD720p60, 1280,720,60,1,true } {bmdModeHD720p60, 1280, 720, 60, 1, true}
}; };
/* class initialization */ /* class initialization */
@ -294,8 +310,8 @@ gst_decklink_sink_init (GstDecklinkSink * decklinksink,
gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->audiosinkpad); gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->audiosinkpad);
decklinksink->cond = g_cond_new(); decklinksink->cond = g_cond_new ();
decklinksink->mutex = g_mutex_new(); decklinksink->mutex = g_mutex_new ();
decklinksink->mode = 0; decklinksink->mode = 0;
@ -364,7 +380,7 @@ gst_decklink_sink_finalize (GObject * object)
} }
static gboolean static gboolean
gst_decklink_sink_start (GstDecklinkSink *decklinksink) gst_decklink_sink_start (GstDecklinkSink * decklinksink)
{ {
IDeckLinkIterator *iterator; IDeckLinkIterator *iterator;
HRESULT ret; HRESULT ret;
@ -375,18 +391,18 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
iterator = CreateDeckLinkIteratorInstance (); iterator = CreateDeckLinkIteratorInstance ();
if (iterator == NULL) { if (iterator == NULL) {
GST_ERROR("no driver"); GST_ERROR ("no driver");
return FALSE; return FALSE;
} }
ret = iterator->Next (&decklinksink->decklink); ret = iterator->Next (&decklinksink->decklink);
if (ret != S_OK) { if (ret != S_OK) {
GST_ERROR("no card"); GST_ERROR ("no card");
return FALSE; return FALSE;
} }
ret = decklinksink->decklink->QueryInterface (IID_IDeckLinkOutput, ret = decklinksink->decklink->QueryInterface (IID_IDeckLinkOutput,
(void **)&decklinksink->output); (void **) &decklinksink->output);
if (ret != S_OK) { if (ret != S_OK) {
GST_ERROR ("no output"); GST_ERROR ("no output");
return FALSE; return FALSE;
@ -424,7 +440,8 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
} }
//decklinksink->video_enabled = TRUE; //decklinksink->video_enabled = TRUE;
decklinksink->output->SetScheduledFrameCompletionCallback (decklinksink->callback); decklinksink->output->
SetScheduledFrameCompletionCallback (decklinksink->callback);
if (0) { if (0) {
ret = decklinksink->output->EnableAudioOutput (bmdAudioSampleRate48kHz, ret = decklinksink->output->EnableAudioOutput (bmdAudioSampleRate48kHz,
@ -441,7 +458,7 @@ gst_decklink_sink_start (GstDecklinkSink *decklinksink)
} }
static gboolean static gboolean
gst_decklink_sink_force_stop (GstDecklinkSink *decklinksink) gst_decklink_sink_force_stop (GstDecklinkSink * decklinksink)
{ {
g_mutex_lock (decklinksink->mutex); g_mutex_lock (decklinksink->mutex);
decklinksink->stop = TRUE; decklinksink->stop = TRUE;
@ -452,7 +469,7 @@ gst_decklink_sink_force_stop (GstDecklinkSink *decklinksink)
} }
static gboolean static gboolean
gst_decklink_sink_stop (GstDecklinkSink *decklinksink) gst_decklink_sink_stop (GstDecklinkSink * decklinksink)
{ {
decklinksink->output->StopScheduledPlayback (0, NULL, 0); decklinksink->output->StopScheduledPlayback (0, NULL, 0);
decklinksink->output->DisableAudioOutput (); decklinksink->output->DisableAudioOutput ();
@ -773,8 +790,8 @@ gst_decklink_sink_videosink_query (GstPad * pad, GstQuery * query)
} }
static GstFlowReturn static GstFlowReturn
gst_decklink_sink_videosink_bufferalloc (GstPad * pad, guint64 offset, guint size, gst_decklink_sink_videosink_bufferalloc (GstPad * pad, guint64 offset,
GstCaps * caps, GstBuffer ** buf) guint size, GstCaps * caps, GstBuffer ** buf)
{ {
GstDecklinkSink *decklinksink; GstDecklinkSink *decklinksink;
@ -984,8 +1001,8 @@ gst_decklink_sink_audiosink_query (GstPad * pad, GstQuery * query)
} }
static GstFlowReturn static GstFlowReturn
gst_decklink_sink_audiosink_bufferalloc (GstPad * pad, guint64 offset, guint size, gst_decklink_sink_audiosink_bufferalloc (GstPad * pad, guint64 offset,
GstCaps * caps, GstBuffer ** buf) guint size, GstCaps * caps, GstBuffer ** buf)
{ {
GstDecklinkSink *decklinksink; GstDecklinkSink *decklinksink;
@ -1020,10 +1037,10 @@ gst_decklink_sink_audiosink_iterintlink (GstPad * pad)
HRESULT HRESULT
Output::ScheduledFrameCompleted (IDeckLinkVideoFrame * completedFrame, Output::ScheduledFrameCompleted (IDeckLinkVideoFrame * completedFrame,
BMDOutputFrameCompletionResult result) BMDOutputFrameCompletionResult result)
{ {
GST_DEBUG("ScheduledFrameCompleted"); GST_DEBUG ("ScheduledFrameCompleted");
g_mutex_lock (decklinksink->mutex); g_mutex_lock (decklinksink->mutex);
g_cond_signal (decklinksink->cond); g_cond_signal (decklinksink->cond);
@ -1036,15 +1053,14 @@ Output::ScheduledFrameCompleted (IDeckLinkVideoFrame * completedFrame,
HRESULT HRESULT
Output::ScheduledPlaybackHasStopped () Output::ScheduledPlaybackHasStopped ()
{ {
GST_ERROR("ScheduledPlaybackHasStopped"); GST_ERROR ("ScheduledPlaybackHasStopped");
return S_OK; return S_OK;
} }
HRESULT HRESULT
Output::RenderAudioSamples (bool preroll) Output::RenderAudioSamples (bool preroll)
{ {
GST_ERROR("RenderAudioSamples"); GST_ERROR ("RenderAudioSamples");
return S_OK; return S_OK;
} }

View File

@ -68,36 +68,48 @@ static gboolean gst_decklink_src_send_event (GstElement * element,
static gboolean gst_decklink_src_query (GstElement * element, GstQuery * query); static gboolean gst_decklink_src_query (GstElement * element, GstQuery * query);
static GstCaps *gst_decklink_src_audio_src_getcaps (GstPad * pad); static GstCaps *gst_decklink_src_audio_src_getcaps (GstPad * pad);
static gboolean gst_decklink_src_audio_src_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_src_audio_src_setcaps (GstPad * pad,
static gboolean gst_decklink_src_audio_src_acceptcaps (GstPad * pad, GstCaps * caps); GstCaps * caps);
static void gst_decklink_src_audio_src_fixatecaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_src_audio_src_acceptcaps (GstPad * pad,
GstCaps * caps);
static void gst_decklink_src_audio_src_fixatecaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_decklink_src_audio_src_activate (GstPad * pad); static gboolean gst_decklink_src_audio_src_activate (GstPad * pad);
static gboolean gst_decklink_src_audio_src_activatepush (GstPad * pad, static gboolean gst_decklink_src_audio_src_activatepush (GstPad * pad,
gboolean active); gboolean active);
static gboolean gst_decklink_src_audio_src_activatepull (GstPad * pad, static gboolean gst_decklink_src_audio_src_activatepull (GstPad * pad,
gboolean active); gboolean active);
static GstPadLinkReturn gst_decklink_src_audio_src_link (GstPad * pad, GstPad * peer); static GstPadLinkReturn gst_decklink_src_audio_src_link (GstPad * pad,
GstPad * peer);
static GstFlowReturn gst_decklink_src_audio_src_getrange (GstPad * pad, static GstFlowReturn gst_decklink_src_audio_src_getrange (GstPad * pad,
guint64 offset, guint length, GstBuffer ** buffer); guint64 offset, guint length, GstBuffer ** buffer);
static gboolean gst_decklink_src_audio_src_event (GstPad * pad, GstEvent * event); static gboolean gst_decklink_src_audio_src_event (GstPad * pad,
static gboolean gst_decklink_src_audio_src_query (GstPad * pad, GstQuery * query); GstEvent * event);
static gboolean gst_decklink_src_audio_src_query (GstPad * pad,
GstQuery * query);
static GstIterator *gst_decklink_src_audio_src_iterintlink (GstPad * pad); static GstIterator *gst_decklink_src_audio_src_iterintlink (GstPad * pad);
static GstCaps *gst_decklink_src_video_src_getcaps (GstPad * pad); static GstCaps *gst_decklink_src_video_src_getcaps (GstPad * pad);
static gboolean gst_decklink_src_video_src_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_src_video_src_setcaps (GstPad * pad,
static gboolean gst_decklink_src_video_src_acceptcaps (GstPad * pad, GstCaps * caps); GstCaps * caps);
static void gst_decklink_src_video_src_fixatecaps (GstPad * pad, GstCaps * caps); static gboolean gst_decklink_src_video_src_acceptcaps (GstPad * pad,
GstCaps * caps);
static void gst_decklink_src_video_src_fixatecaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_decklink_src_video_src_activate (GstPad * pad); static gboolean gst_decklink_src_video_src_activate (GstPad * pad);
static gboolean gst_decklink_src_video_src_activatepush (GstPad * pad, static gboolean gst_decklink_src_video_src_activatepush (GstPad * pad,
gboolean active); gboolean active);
static gboolean gst_decklink_src_video_src_activatepull (GstPad * pad, static gboolean gst_decklink_src_video_src_activatepull (GstPad * pad,
gboolean active); gboolean active);
static GstPadLinkReturn gst_decklink_src_video_src_link (GstPad * pad, GstPad * peer); static GstPadLinkReturn gst_decklink_src_video_src_link (GstPad * pad,
GstPad * peer);
static GstFlowReturn gst_decklink_src_video_src_getrange (GstPad * pad, static GstFlowReturn gst_decklink_src_video_src_getrange (GstPad * pad,
guint64 offset, guint length, GstBuffer ** buffer); guint64 offset, guint length, GstBuffer ** buffer);
static gboolean gst_decklink_src_video_src_event (GstPad * pad, GstEvent * event); static gboolean gst_decklink_src_video_src_event (GstPad * pad,
static gboolean gst_decklink_src_video_src_query (GstPad * pad, GstQuery * query); GstEvent * event);
static gboolean gst_decklink_src_video_src_query (GstPad * pad,
GstQuery * query);
static GstIterator *gst_decklink_src_video_src_iterintlink (GstPad * pad); static GstIterator *gst_decklink_src_video_src_iterintlink (GstPad * pad);
static void gst_decklink_src_task (void *priv); static void gst_decklink_src_task (void *priv);
@ -121,28 +133,27 @@ GST_STATIC_PAD_TEMPLATE ("audiosrc",
",framerate=" #n "/" #d ",interlaced=" #i ",framerate=" #n "/" #d ",interlaced=" #i
static GstStaticPadTemplate gst_decklink_src_video_src_template = static GstStaticPadTemplate gst_decklink_src_video_src_template =
GST_STATIC_PAD_TEMPLATE ("videosrc", GST_STATIC_PAD_TEMPLATE ("videosrc",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ( GST_STATIC_CAPS (MODE (720, 486, 30000, 1001, true) ";"
MODE(720,486,30000,1001,true) ";" MODE (720, 486, 24000, 1001, true) ";"
MODE(720,486,24000,1001,true) ";" MODE (720, 576, 25, 1, true) ";"
MODE(720,576,25,1,true) ";" MODE (1920, 1080, 24000, 1001, false) ";"
MODE(1920,1080,24000,1001,false) ";" MODE (1920, 1080, 24, 1, false) ";"
MODE(1920,1080,24,1,false) ";" MODE (1920, 1080, 25, 1, false) ";"
MODE(1920,1080,25,1,false) ";" MODE (1920, 1080, 30000, 1001, false) ";"
MODE(1920,1080,30000,1001,false) ";" MODE (1920, 1080, 30, 1, false) ";"
MODE(1920,1080,30,1,false) ";" MODE (1920, 1080, 25, 1, true) ";"
MODE(1920,1080,25,1,true) ";" MODE (1920, 1080, 30000, 1001, true) ";"
MODE(1920,1080,30000,1001,true) ";" MODE (1920, 1080, 30, 1, true) ";"
MODE(1920,1080,30,1,true) ";" MODE (1280, 720, 50, 1, true) ";"
MODE(1280,720,50,1,true) ";" MODE (1280, 720, 60000, 1001, true) ";" MODE (1280, 720, 60, 1, true)
MODE(1280,720,60000,1001,true) ";"
MODE(1280,720,60,1,true)
)); ));
typedef struct _DecklinkMode DecklinkMode; typedef struct _DecklinkMode DecklinkMode;
struct _DecklinkMode { struct _DecklinkMode
{
BMDDisplayMode mode; BMDDisplayMode mode;
int width; int width;
int height; int height;
@ -152,20 +163,20 @@ struct _DecklinkMode {
}; };
static DecklinkMode modes[] = { static DecklinkMode modes[] = {
{ bmdModeNTSC, 720,486,30000,1001,true }, {bmdModeNTSC, 720, 486, 30000, 1001, true},
{ bmdModeNTSC2398, 720,486,24000,1001,true }, {bmdModeNTSC2398, 720, 486, 24000, 1001, true},
{ bmdModePAL, 720,576,25,1,true }, {bmdModePAL, 720, 576, 25, 1, true},
{ bmdModeHD1080p2398, 1920,1080,24000,1001,false }, {bmdModeHD1080p2398, 1920, 1080, 24000, 1001, false},
{ bmdModeHD1080p24, 1920,1080,24,1,false }, {bmdModeHD1080p24, 1920, 1080, 24, 1, false},
{ bmdModeHD1080p25, 1920,1080,25,1,false }, {bmdModeHD1080p25, 1920, 1080, 25, 1, false},
{ bmdModeHD1080p2997, 1920,1080,30000,1001,false }, {bmdModeHD1080p2997, 1920, 1080, 30000, 1001, false},
{ bmdModeHD1080p30, 1920,1080,30,1,false }, {bmdModeHD1080p30, 1920, 1080, 30, 1, false},
{ bmdModeHD1080i50, 1920,1080,25,1,true }, {bmdModeHD1080i50, 1920, 1080, 25, 1, true},
{ bmdModeHD1080i5994, 1920,1080,30000,1001,true }, {bmdModeHD1080i5994, 1920, 1080, 30000, 1001, true},
{ bmdModeHD1080i6000, 1920,1080,30,1,true }, {bmdModeHD1080i6000, 1920, 1080, 30, 1, true},
{ bmdModeHD720p50, 1280,720,50,1,true }, {bmdModeHD720p50, 1280, 720, 50, 1, true},
{ bmdModeHD720p5994, 1280,720,60000,1001,true }, {bmdModeHD720p5994, 1280, 720, 60000, 1001, true},
{ bmdModeHD720p60, 1280,720,60,1,true } {bmdModeHD720p60, 1280, 720, 60, 1, true}
}; };
@ -226,7 +237,8 @@ gst_decklink_src_init (GstDecklinkSrc * decklinksrc,
gst_task_set_lock (decklinksrc->task, &decklinksrc->task_mutex); gst_task_set_lock (decklinksrc->task, &decklinksrc->task_mutex);
decklinksrc->audiosrcpad = decklinksrc->audiosrcpad =
gst_pad_new_from_static_template (&gst_decklink_src_audio_src_template, "audiosrc"); gst_pad_new_from_static_template (&gst_decklink_src_audio_src_template,
"audiosrc");
gst_pad_set_getcaps_function (decklinksrc->audiosrcpad, gst_pad_set_getcaps_function (decklinksrc->audiosrcpad,
GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getcaps)); GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getcaps));
gst_pad_set_setcaps_function (decklinksrc->audiosrcpad, gst_pad_set_setcaps_function (decklinksrc->audiosrcpad,
@ -256,7 +268,8 @@ gst_decklink_src_init (GstDecklinkSrc * decklinksrc,
decklinksrc->videosrcpad = decklinksrc->videosrcpad =
gst_pad_new_from_static_template (&gst_decklink_src_video_src_template, "videosrc"); gst_pad_new_from_static_template (&gst_decklink_src_video_src_template,
"videosrc");
gst_pad_set_getcaps_function (decklinksrc->videosrcpad, gst_pad_set_getcaps_function (decklinksrc->videosrcpad,
GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getcaps)); GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getcaps));
gst_pad_set_setcaps_function (decklinksrc->videosrcpad, gst_pad_set_setcaps_function (decklinksrc->videosrcpad,
@ -284,8 +297,8 @@ gst_decklink_src_init (GstDecklinkSrc * decklinksrc,
gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->videosrcpad); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->videosrcpad);
decklinksrc->cond = g_cond_new(); decklinksrc->cond = g_cond_new ();
decklinksrc->mutex = g_mutex_new(); decklinksrc->mutex = g_mutex_new ();
decklinksrc->copy_data = TRUE; decklinksrc->copy_data = TRUE;
decklinksrc->mode = 0; decklinksrc->mode = 0;
@ -395,13 +408,13 @@ gst_decklink_src_start (GstElement * element)
iterator = CreateDeckLinkIteratorInstance (); iterator = CreateDeckLinkIteratorInstance ();
if (iterator == NULL) { if (iterator == NULL) {
GST_ERROR("no driver"); GST_ERROR ("no driver");
return FALSE; return FALSE;
} }
ret = iterator->Next (&decklinksrc->decklink); ret = iterator->Next (&decklinksrc->decklink);
if (ret != S_OK) { if (ret != S_OK) {
GST_ERROR("no card"); GST_ERROR ("no card");
return FALSE; return FALSE;
} }
@ -418,7 +431,7 @@ gst_decklink_src_start (GstElement * element)
ret = decklinksrc->input->GetDisplayModeIterator (&mode_iterator); ret = decklinksrc->input->GetDisplayModeIterator (&mode_iterator);
if (ret != S_OK) { if (ret != S_OK) {
GST_ERROR("failed to get display mode iterator"); GST_ERROR ("failed to get display mode iterator");
return FALSE; return FALSE;
} }
@ -428,7 +441,7 @@ gst_decklink_src_start (GstElement * element)
mode->GetName (&mode_name); mode->GetName (&mode_name);
GST_ERROR("%d: mode name: %s", i, mode_name); GST_ERROR ("%d: mode name: %s", i, mode_name);
mode->Release (); mode->Release ();
i++; i++;
@ -439,23 +452,24 @@ gst_decklink_src_start (GstElement * element)
input_flags = 0; input_flags = 0;
ret = decklinksrc->input->EnableVideoInput (selected_mode, pixel_format, ret = decklinksrc->input->EnableVideoInput (selected_mode, pixel_format,
input_flags); input_flags);
if (ret != S_OK){ if (ret != S_OK) {
GST_ERROR("enable video input failed"); GST_ERROR ("enable video input failed");
return FALSE; return FALSE;
} }
sample_depth = 16; sample_depth = 16;
channels = 2; channels = 2;
ret = decklinksrc->input->EnableAudioInput (bmdAudioSampleRate48kHz, sample_depth, ret =
channels); decklinksrc->input->EnableAudioInput (bmdAudioSampleRate48kHz,
if (ret != S_OK){ sample_depth, channels);
GST_ERROR("enable video input failed"); if (ret != S_OK) {
GST_ERROR ("enable video input failed");
return FALSE; return FALSE;
} }
ret = decklinksrc->input->StartStreams (); ret = decklinksrc->input->StartStreams ();
if (ret != S_OK) { if (ret != S_OK) {
GST_ERROR("start streams failed"); GST_ERROR ("start streams failed");
return FALSE; return FALSE;
} }
@ -960,7 +974,7 @@ gst_decklink_src_video_src_iterintlink (GstPad * pad)
static void static void
video_frame_free (void *data) video_frame_free (void *data)
{ {
IDeckLinkVideoInputFrame *video_frame = (IDeckLinkVideoInputFrame *)data; IDeckLinkVideoInputFrame *video_frame = (IDeckLinkVideoInputFrame *) data;
video_frame->Release (); video_frame->Release ();
} }
@ -992,31 +1006,33 @@ gst_decklink_src_task (void *priv)
g_mutex_unlock (decklinksrc->mutex); g_mutex_unlock (decklinksrc->mutex);
if (decklinksrc->stop) { if (decklinksrc->stop) {
GST_ERROR("stopping task"); GST_ERROR ("stopping task");
return; return;
} }
if (dropped_frames > 0) { if (dropped_frames > 0) {
GST_ELEMENT_ERROR(decklinksrc, RESOURCE, READ, (NULL), (NULL)); GST_ELEMENT_ERROR (decklinksrc, RESOURCE, READ, (NULL), (NULL));
/* ERROR */ /* ERROR */
return; return;
} }
video_frame->GetBytes (&data); video_frame->GetBytes (&data);
if (decklinksrc->copy_data) { if (decklinksrc->copy_data) {
buffer = gst_buffer_new_and_alloc (decklinksrc->width * decklinksrc->height * 2); buffer =
gst_buffer_new_and_alloc (decklinksrc->width * decklinksrc->height * 2);
memcpy (GST_BUFFER_DATA (buffer), data, decklinksrc->width * decklinksrc->height * 2); memcpy (GST_BUFFER_DATA (buffer), data,
decklinksrc->width * decklinksrc->height * 2);
video_frame->Release (); video_frame->Release ();
} else { } else {
buffer = gst_buffer_new (); buffer = gst_buffer_new ();
GST_BUFFER_SIZE (buffer) = decklinksrc->width * decklinksrc->height * 2; GST_BUFFER_SIZE (buffer) = decklinksrc->width * decklinksrc->height * 2;
GST_BUFFER_DATA (buffer) = (guint8 *)data; GST_BUFFER_DATA (buffer) = (guint8 *) data;
GST_BUFFER_FREE_FUNC (buffer) = video_frame_free; GST_BUFFER_FREE_FUNC (buffer) = video_frame_free;
GST_BUFFER_MALLOCDATA (buffer) = (guint8 *)video_frame; GST_BUFFER_MALLOCDATA (buffer) = (guint8 *) video_frame;
} }
GST_BUFFER_TIMESTAMP (buffer) = GST_BUFFER_TIMESTAMP (buffer) =
@ -1024,33 +1040,31 @@ gst_decklink_src_task (void *priv)
decklinksrc->fps_d, decklinksrc->fps_n); decklinksrc->fps_d, decklinksrc->fps_n);
GST_BUFFER_DURATION (buffer) = GST_BUFFER_DURATION (buffer) =
gst_util_uint64_scale_int ((decklinksrc->num_frames + 1) * GST_SECOND, gst_util_uint64_scale_int ((decklinksrc->num_frames + 1) * GST_SECOND,
decklinksrc->fps_d, decklinksrc->fps_n) - decklinksrc->fps_d, decklinksrc->fps_n) - GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_OFFSET (buffer) = decklinksrc->num_frames; GST_BUFFER_OFFSET (buffer) = decklinksrc->num_frames;
if (decklinksrc->num_frames == 0) { if (decklinksrc->num_frames == 0) {
GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
} }
decklinksrc->num_frames ++; decklinksrc->num_frames++;
if (decklinksrc->video_caps == NULL) { if (decklinksrc->video_caps == NULL) {
decklinksrc->video_caps = gst_caps_new_simple ("video/x-raw-yuv", decklinksrc->video_caps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC('U','Y','V','Y'), "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
"width", G_TYPE_INT, decklinksrc->width, "width", G_TYPE_INT, decklinksrc->width,
"height", G_TYPE_INT, decklinksrc->height, "height", G_TYPE_INT, decklinksrc->height,
"framerate", GST_TYPE_FRACTION, "framerate", GST_TYPE_FRACTION,
decklinksrc->fps_n, decklinksrc->fps_d, decklinksrc->fps_n, decklinksrc->fps_d,
"interlaced", G_TYPE_BOOLEAN, decklinksrc->interlaced, "interlaced", G_TYPE_BOOLEAN, decklinksrc->interlaced, NULL);
NULL);
} }
gst_buffer_set_caps (buffer, decklinksrc->video_caps); gst_buffer_set_caps (buffer, decklinksrc->video_caps);
ret = gst_pad_push (decklinksrc->videosrcpad, buffer); ret = gst_pad_push (decklinksrc->videosrcpad, buffer);
if (ret != GST_FLOW_OK) { if (ret != GST_FLOW_OK) {
GST_ELEMENT_ERROR(decklinksrc, CORE, NEGOTIATION, (NULL), (NULL)); GST_ELEMENT_ERROR (decklinksrc, CORE, NEGOTIATION, (NULL), (NULL));
} }
n_samples = audio_frame->GetSampleFrameCount(); n_samples = audio_frame->GetSampleFrameCount ();
audio_frame->GetBytes (&data); audio_frame->GetBytes (&data);
audio_buffer = gst_buffer_new_and_alloc (n_samples * 2 * 2); audio_buffer = gst_buffer_new_and_alloc (n_samples * 2 * 2);
memcpy (GST_BUFFER_DATA (audio_buffer), data, n_samples * 2 * 2); memcpy (GST_BUFFER_DATA (audio_buffer), data, n_samples * 2 * 2);
@ -1060,8 +1074,9 @@ gst_decklink_src_task (void *priv)
gst_util_uint64_scale_int (decklinksrc->num_audio_samples * GST_SECOND, gst_util_uint64_scale_int (decklinksrc->num_audio_samples * GST_SECOND,
1, 48000); 1, 48000);
GST_BUFFER_DURATION (audio_buffer) = GST_BUFFER_DURATION (audio_buffer) =
gst_util_uint64_scale_int ((decklinksrc->num_audio_samples + n_samples) * GST_SECOND, gst_util_uint64_scale_int ((decklinksrc->num_audio_samples +
1, 48000) - GST_BUFFER_TIMESTAMP (audio_buffer); n_samples) * GST_SECOND, 1,
48000) - GST_BUFFER_TIMESTAMP (audio_buffer);
decklinksrc->num_audio_samples += n_samples; decklinksrc->num_audio_samples += n_samples;
if (decklinksrc->audio_caps == NULL) { if (decklinksrc->audio_caps == NULL) {
@ -1070,16 +1085,12 @@ gst_decklink_src_task (void *priv)
"signed", G_TYPE_BOOLEAN, TRUE, "signed", G_TYPE_BOOLEAN, TRUE,
"depth", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
"width", G_TYPE_INT, 16, "width", G_TYPE_INT, 16,
"channels", G_TYPE_INT, 2, "channels", G_TYPE_INT, 2, "rate", G_TYPE_INT, 48000, NULL);
"rate", G_TYPE_INT, 48000,
NULL);
} }
gst_buffer_set_caps (audio_buffer, decklinksrc->audio_caps); gst_buffer_set_caps (audio_buffer, decklinksrc->audio_caps);
ret = gst_pad_push (decklinksrc->audiosrcpad, audio_buffer); ret = gst_pad_push (decklinksrc->audiosrcpad, audio_buffer);
if (ret != GST_FLOW_OK) { if (ret != GST_FLOW_OK) {
GST_ELEMENT_ERROR(decklinksrc, CORE, NEGOTIATION, (NULL), (NULL)); GST_ELEMENT_ERROR (decklinksrc, CORE, NEGOTIATION, (NULL), (NULL));
} }
} }