22 #include <DeckLinkAPI.h>
24 #include <DeckLinkAPI_i.c>
27 #include <DeckLinkAPIDispatch.cpp>
32 #include <semaphore.h>
91 virtual BMDPixelFormat STDMETHODCALLTYPE
GetPixelFormat(
void) {
return bmdFormat8BitYUV; }
92 virtual BMDFrameFlags STDMETHODCALLTYPE
GetFlags (
void) {
return bmdVideoOutputFlagDefault; }
134 static IDeckLinkIterator *CreateDeckLinkIteratorInstance(
void)
136 IDeckLinkIterator *iter;
138 if (CoInitialize(NULL) !=
S_OK) {
143 if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
144 IID_IDeckLinkIterator, (
void**) &iter) !=
S_OK) {
160 int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
163 WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
166 #define DECKLINK_STR OLECHAR *
167 #define DECKLINK_STRDUP dup_wchar_to_utf8
169 #define DECKLINK_STR const char *
170 #define DECKLINK_STRDUP av_strdup
176 HRESULT hr = This->GetDisplayName(&tmpDisplayName);
180 free((
void *) tmpDisplayName);
186 int tb_num,
int tb_den)
188 BMDDisplayModeSupport support;
189 IDeckLinkDisplayMode *
mode;
201 mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
203 if (bmd_width == width && bmd_height == height &&
204 bmd_tb_num == tb_num && bmd_tb_den == tb_den) {
205 ctx->
bmd_mode = mode->GetDisplayMode();
214 if (ctx->
bmd_mode == bmdModeUnknown)
216 if (ctx->
dlo->DoesSupportVideoMode(ctx->
bmd_mode, bmdFormat8BitYUV,
217 bmdVideoOutputFlagDefault,
218 &support, NULL) !=
S_OK)
220 if (support == bmdDisplayModeSupported)
239 " Only AV_PIX_FMT_UYVY422 is supported.\n");
245 " Check available formats with -list_formats 1.\n");
248 if (
ctx->dlo->EnableVideoOutput(
ctx->bmd_mode,
249 bmdVideoOutputFlagDefault) !=
S_OK) {
256 ctx->dlo->SetScheduledFrameCompletionCallback(
ctx->callback);
261 ctx->frames_preroll /= 1000;
264 ctx->frames_buffer =
ctx->frames_preroll * 2;
265 ctx->frames_buffer =
FFMIN(
ctx->frames_buffer, 60);
266 sem_init(&
ctx->semaphore, 0,
ctx->frames_buffer);
288 " Only 48kHz is supported.\n");
293 " Only stereo and 7.1 are supported.\n");
296 if (
ctx->dlo->EnableAudioOutput(bmdAudioSampleRate48kHz,
297 bmdAudioSampleType16bitInteger,
299 bmdAudioOutputStreamTimestamped) !=
S_OK) {
303 if (
ctx->dlo->BeginAudioPreroll() !=
S_OK) {
322 if (
ctx->playback_started) {
324 ctx->dlo->StopScheduledPlayback(
ctx->last_pts *
ctx->bmd_tb_num,
325 &actual,
ctx->bmd_tb_den);
326 ctx->dlo->DisableVideoOutput();
328 ctx->dlo->DisableAudioOutput();
337 delete ctx->callback;
339 sem_destroy(&
ctx->semaphore);
363 tmp->width =
ctx->bmd_width;
364 tmp->height =
ctx->bmd_height;
382 (
void *) avframe->
data[0]);
389 sem_wait(&
ctx->semaphore);
392 hr =
ctx->dlo->ScheduleVideoFrame((
struct IDeckLinkVideoFrame *)
frame,
393 pkt->
pts *
ctx->bmd_tb_num,
394 ctx->bmd_tb_num,
ctx->bmd_tb_den);
397 " error %08x.\n", (uint32_t) hr);
402 ctx->dlo->GetBufferedVideoFrameCount(&buffered);
404 if (pkt->
pts > 2 && buffered <= 2)
406 " Video may misbehave!\n");
409 if (!
ctx->playback_started && pkt->
pts >
ctx->frames_preroll) {
411 if (
ctx->audio &&
ctx->dlo->EndAudioPreroll() !=
S_OK) {
416 if (
ctx->dlo->StartScheduledPlayback(0,
ctx->bmd_tb_den, 1.0) !=
S_OK) {
420 ctx->playback_started = 1;
430 int sample_count = pkt->
size / (
ctx->channels << 1);
433 ctx->dlo->GetBufferedAudioSampleFrameCount(&buffered);
434 if (pkt->
pts > 1 && !buffered)
436 " Audio will misbehave!\n");
438 if (
ctx->dlo->ScheduleAudioSamples(pkt->
data, sample_count, pkt->
pts,
439 bmdAudioSampleRate48kHz, NULL) !=
S_OK) {
453 IDeckLinkIterator *iter;
454 IDeckLink *dl = NULL;
465 iter = CreateDeckLinkIteratorInstance();
472 if (
ctx->list_devices) {
474 while (iter->Next(&dl) ==
S_OK) {
475 const char *displayName;
486 while (iter->Next(&dl) ==
S_OK) {
487 const char *displayName;
489 if (!strcmp(avctx->
filename, displayName)) {
504 if (
ctx->dl->QueryInterface(IID_IDeckLinkOutput, (
void **) &
ctx->dlo) !=
S_OK) {
511 if (
ctx->dlo->GetDisplayModeIterator(&
ctx->itermode) !=
S_OK) {
518 if (
ctx->list_formats) {
519 IDeckLinkDisplayMode *
mode;
523 while (
ctx->itermode->Next(&mode) ==
S_OK) {
524 BMDTimeValue tb_num, tb_den;
525 mode->GetFrameRate(&tb_num, &tb_den);
527 mode->GetWidth(), mode->GetHeight(),
528 (int) tb_den, (
int) tb_num);
529 switch (mode->GetFieldDominance()) {
530 case bmdLowerFieldFirst:
532 case bmdUpperFieldFirst:
539 ctx->itermode->Release();
560 ctx->itermode->Release();