2 * Blackmagic DeckLink output
3 * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <DeckLinkAPI.h>
25 #include <semaphore.h>
28 #include "libavformat/avformat.h"
29 #include "libavformat/internal.h"
30 #include "libavutil/imgutils.h"
33 #include "decklink_common.h"
34 #include "decklink_dec.h"
36 static void avpacket_queue_init(AVFormatContext
*avctx
, AVPacketQueue
*q
)
38 memset(q
, 0, sizeof(AVPacketQueue
));
39 pthread_mutex_init(&q
->mutex
, NULL
);
40 pthread_cond_init(&q
->cond
, NULL
);
44 static void avpacket_queue_flush(AVPacketQueue
*q
)
46 AVPacketList
*pkt
, *pkt1
;
48 pthread_mutex_lock(&q
->mutex
);
49 for (pkt
= q
->first_pkt
; pkt
!= NULL
; pkt
= pkt1
) {
51 av_free_packet(&pkt
->pkt
);
58 pthread_mutex_unlock(&q
->mutex
);
61 static void avpacket_queue_end(AVPacketQueue
*q
)
63 avpacket_queue_flush(q
);
64 pthread_mutex_destroy(&q
->mutex
);
65 pthread_cond_destroy(&q
->cond
);
68 static unsigned long long avpacket_queue_size(AVPacketQueue
*q
)
70 unsigned long long size
;
71 pthread_mutex_lock(&q
->mutex
);
73 pthread_mutex_unlock(&q
->mutex
);
77 static int avpacket_queue_put(AVPacketQueue
*q
, AVPacket
*pkt
)
81 // Drop Packet if queue size is > 1GB
82 if (avpacket_queue_size(q
) > 1024 * 1024 * 1024 ) {
83 av_log(q
->avctx
, AV_LOG_WARNING
, "Decklink input buffer overrun!\n");
86 /* duplicate the packet */
87 if (av_dup_packet(pkt
) < 0) {
91 pkt1
= (AVPacketList
*)av_malloc(sizeof(AVPacketList
));
98 pthread_mutex_lock(&q
->mutex
);
103 q
->last_pkt
->next
= pkt1
;
108 q
->size
+= pkt1
->pkt
.size
+ sizeof(*pkt1
);
110 pthread_cond_signal(&q
->cond
);
112 pthread_mutex_unlock(&q
->mutex
);
116 static int avpacket_queue_get(AVPacketQueue
*q
, AVPacket
*pkt
, int block
)
121 pthread_mutex_lock(&q
->mutex
);
126 q
->first_pkt
= pkt1
->next
;
131 q
->size
-= pkt1
->pkt
.size
+ sizeof(*pkt1
);
140 pthread_cond_wait(&q
->cond
, &q
->mutex
);
143 pthread_mutex_unlock(&q
->mutex
);
147 class decklink_input_callback
: public IDeckLinkInputCallback
150 decklink_input_callback(AVFormatContext
*_avctx
);
151 ~decklink_input_callback();
153 virtual HRESULT STDMETHODCALLTYPE
QueryInterface(REFIID iid
, LPVOID
*ppv
) { return E_NOINTERFACE
; }
154 virtual ULONG STDMETHODCALLTYPE
AddRef(void);
155 virtual ULONG STDMETHODCALLTYPE
Release(void);
156 virtual HRESULT STDMETHODCALLTYPE
VideoInputFormatChanged(BMDVideoInputFormatChangedEvents
, IDeckLinkDisplayMode
*, BMDDetectedVideoInputFormatFlags
);
157 virtual HRESULT STDMETHODCALLTYPE
VideoInputFrameArrived(IDeckLinkVideoInputFrame
*, IDeckLinkAudioInputPacket
*);
161 pthread_mutex_t m_mutex
;
162 AVFormatContext
*avctx
;
165 int64_t initial_video_pts
;
166 int64_t initial_audio_pts
;
169 decklink_input_callback::decklink_input_callback(AVFormatContext
*_avctx
) : m_refCount(0)
172 decklink_cctx
*cctx
= (struct decklink_cctx
*) avctx
->priv_data
;
173 ctx
= (struct decklink_ctx
*) cctx
->ctx
;
174 initial_audio_pts
= initial_video_pts
= AV_NOPTS_VALUE
;
175 pthread_mutex_init(&m_mutex
, NULL
);
178 decklink_input_callback::~decklink_input_callback()
180 pthread_mutex_destroy(&m_mutex
);
183 ULONG
decklink_input_callback::AddRef(void)
185 pthread_mutex_lock(&m_mutex
);
187 pthread_mutex_unlock(&m_mutex
);
189 return (ULONG
)m_refCount
;
192 ULONG
decklink_input_callback::Release(void)
194 pthread_mutex_lock(&m_mutex
);
196 pthread_mutex_unlock(&m_mutex
);
198 if (m_refCount
== 0) {
203 return (ULONG
)m_refCount
;
206 HRESULT
decklink_input_callback::VideoInputFrameArrived(
207 IDeckLinkVideoInputFrame
*videoFrame
, IDeckLinkAudioInputPacket
*audioFrame
)
210 void *audioFrameBytes
;
211 BMDTimeValue frameTime
;
212 BMDTimeValue frameDuration
;
216 // Handle Video Frame
220 av_init_packet(&pkt
);
221 c
= ctx
->video_st
->codec
;
222 if (ctx
->frameCount
% 25 == 0) {
223 unsigned long long qsize
= avpacket_queue_size(&ctx
->queue
);
224 av_log(avctx
, AV_LOG_DEBUG
,
225 "Frame received (#%lu) - Valid (%liB) - QSize %fMB\n",
227 videoFrame
->GetRowBytes() * videoFrame
->GetHeight(),
228 (double)qsize
/ 1024 / 1024);
231 videoFrame
->GetBytes(&frameBytes
);
232 videoFrame
->GetStreamTime(&frameTime
, &frameDuration
,
233 ctx
->video_st
->time_base
.den
);
235 if (videoFrame
->GetFlags() & bmdFrameHasNoInputSource
) {
237 0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
238 0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
239 int width
= videoFrame
->GetWidth();
240 int height
= videoFrame
->GetHeight();
241 unsigned *p
= (unsigned *)frameBytes
;
243 for (int y
= 0; y
< height
; y
++) {
244 for (int x
= 0; x
< width
; x
+= 2)
245 *p
++ = bars
[(x
* 8) / width
];
249 av_log(avctx
, AV_LOG_WARNING
, "Frame received (#%lu) - No input signal detected "
250 "- Frames dropped %u\n", ctx
->frameCount
, ++ctx
->dropped
);
255 av_log(avctx
, AV_LOG_WARNING
, "Frame received (#%lu) - Input returned "
256 "- Frames dropped %u\n", ctx
->frameCount
, ++ctx
->dropped
);
261 pkt
.pts
= frameTime
/ ctx
->video_st
->time_base
.num
;
263 if (initial_video_pts
== AV_NOPTS_VALUE
) {
264 initial_video_pts
= pkt
.pts
;
267 pkt
.pts
-= initial_video_pts
;
270 pkt
.duration
= frameDuration
;
271 //To be made sure it still applies
272 pkt
.flags
|= AV_PKT_FLAG_KEY
;
273 pkt
.stream_index
= ctx
->video_st
->index
;
274 pkt
.data
= (uint8_t *)frameBytes
;
275 pkt
.size
= videoFrame
->GetRowBytes() *
276 videoFrame
->GetHeight();
277 //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);
279 if (avpacket_queue_put(&ctx
->queue
, &pkt
) < 0) {
284 // Handle Audio Frame
288 BMDTimeValue audio_pts
;
289 av_init_packet(&pkt
);
291 c
= ctx
->audio_st
->codec
;
293 pkt
.size
= audioFrame
->GetSampleFrameCount() * ctx
->audio_st
->codec
->channels
* (16 / 8);
294 audioFrame
->GetBytes(&audioFrameBytes
);
295 audioFrame
->GetPacketTime(&audio_pts
, ctx
->audio_st
->time_base
.den
);
296 pkt
.pts
= audio_pts
/ ctx
->audio_st
->time_base
.num
;
298 if (initial_audio_pts
== AV_NOPTS_VALUE
) {
299 initial_audio_pts
= pkt
.pts
;
302 pkt
.pts
-= initial_audio_pts
;
305 //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);
306 pkt
.flags
|= AV_PKT_FLAG_KEY
;
307 pkt
.stream_index
= ctx
->audio_st
->index
;
308 pkt
.data
= (uint8_t *)audioFrameBytes
;
311 if (avpacket_queue_put(&ctx
->queue
, &pkt
) < 0) {
319 HRESULT
decklink_input_callback::VideoInputFormatChanged(
320 BMDVideoInputFormatChangedEvents events
, IDeckLinkDisplayMode
*mode
,
321 BMDDetectedVideoInputFormatFlags
)
326 static HRESULT
decklink_start_input(AVFormatContext
*avctx
)
328 struct decklink_cctx
*cctx
= (struct decklink_cctx
*) avctx
->priv_data
;
329 struct decklink_ctx
*ctx
= (struct decklink_ctx
*) cctx
->ctx
;
331 ctx
->input_callback
= new decklink_input_callback(avctx
);
332 ctx
->dli
->SetCallback(ctx
->input_callback
);
333 return ctx
->dli
->StartStreams();
338 av_cold
int ff_decklink_read_close(AVFormatContext
*avctx
)
340 struct decklink_cctx
*cctx
= (struct decklink_cctx
*) avctx
->priv_data
;
341 struct decklink_ctx
*ctx
= (struct decklink_ctx
*) cctx
->ctx
;
343 if (ctx
->capture_started
) {
344 ctx
->dli
->StopStreams();
345 ctx
->dli
->DisableVideoInput();
346 ctx
->dli
->DisableAudioInput();
354 avpacket_queue_end(&ctx
->queue
);
356 av_freep(&cctx
->ctx
);
361 av_cold
int ff_decklink_read_header(AVFormatContext
*avctx
)
363 struct decklink_cctx
*cctx
= (struct decklink_cctx
*) avctx
->priv_data
;
364 struct decklink_ctx
*ctx
;
365 IDeckLinkDisplayModeIterator
*itermode
;
366 IDeckLinkIterator
*iter
;
367 IDeckLink
*dl
= NULL
;
374 ctx
= (struct decklink_ctx
*) av_mallocz(sizeof(struct decklink_ctx
));
376 return AVERROR(ENOMEM
);
377 ctx
->list_devices
= cctx
->list_devices
;
378 ctx
->list_formats
= cctx
->list_formats
;
379 ctx
->preroll
= cctx
->preroll
;
382 iter
= CreateDeckLinkIteratorInstance();
384 av_log(avctx
, AV_LOG_ERROR
, "Could not create DeckLink iterator\n");
388 /* List available devices. */
389 if (ctx
->list_devices
) {
390 ff_decklink_list_devices(avctx
);
394 strcpy (fname
, avctx
->filename
);
395 tmp
=strchr (fname
, '@');
397 mode_num
= atoi (tmp
+1);
402 while (iter
->Next(&dl
) == S_OK
) {
403 const char *displayName
;
404 ff_decklink_get_display_name(dl
, &displayName
);
405 if (!strcmp(fname
, displayName
)) {
406 av_free((void *) displayName
);
410 av_free((void *) displayName
);
415 av_log(avctx
, AV_LOG_ERROR
, "Could not open '%s'\n", fname
);
419 /* Get input device. */
420 if (ctx
->dl
->QueryInterface(IID_IDeckLinkInput
, (void **) &ctx
->dli
) != S_OK
) {
421 av_log(avctx
, AV_LOG_ERROR
, "Could not open output device from '%s'\n",
427 /* List supported formats. */
428 if (ctx
->list_formats
) {
429 ff_decklink_list_formats(avctx
, DIRECTION_IN
);
435 if (ctx
->dli
->GetDisplayModeIterator(&itermode
) != S_OK
) {
436 av_log(avctx
, AV_LOG_ERROR
, "Could not get Display Mode Iterator\n");
442 if (ff_decklink_set_format(avctx
, DIRECTION_IN
, mode_num
) < 0) {
443 av_log(avctx
, AV_LOG_ERROR
, "Could not set mode %d for %s\n", mode_num
, fname
);
451 st
= avformat_new_stream(avctx
, NULL
);
453 av_log(avctx
, AV_LOG_ERROR
, "Cannot add stream\n");
456 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
457 st
->codec
->codec_id
= AV_CODEC_ID_PCM_S16LE
;
458 st
->codec
->sample_rate
= bmdAudioSampleRate48kHz
;
459 st
->codec
->channels
= 2;
460 avpriv_set_pts_info(st
, 64, 1, 1000000); /* 64 bits pts in us */
463 st
= avformat_new_stream(avctx
, NULL
);
465 av_log(avctx
, AV_LOG_ERROR
, "Cannot add stream\n");
468 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
469 st
->codec
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
470 st
->codec
->width
= ctx
->bmd_width
;
471 st
->codec
->height
= ctx
->bmd_height
;
473 st
->codec
->pix_fmt
= AV_PIX_FMT_UYVY422
;
474 st
->codec
->time_base
.den
= ctx
->bmd_tb_den
;
475 st
->codec
->time_base
.num
= ctx
->bmd_tb_num
;
476 st
->codec
->bit_rate
= avpicture_get_size(st
->codec
->pix_fmt
, ctx
->bmd_width
, ctx
->bmd_height
) * 1/av_q2d(st
->codec
->time_base
) * 8;
477 st
->codec
->codec_tag
= MKTAG('U', 'Y', 'V', 'Y');
479 avpriv_set_pts_info(st
, 64, 1, 1000000); /* 64 bits pts in us */
483 result
= ctx
->dli
->EnableAudioInput(bmdAudioSampleRate48kHz
, bmdAudioSampleType16bitInteger
, 2);
485 if (result
!= S_OK
) {
486 av_log(avctx
, AV_LOG_ERROR
, "Cannot enable audio input\n");
490 result
= ctx
->dli
->EnableVideoInput(ctx
->bmd_mode
, bmdFormat8BitYUV
, bmdVideoInputFlagDefault
);
492 if (result
!= S_OK
) {
493 av_log(avctx
, AV_LOG_ERROR
, "Cannot enable video input\n");
497 avpacket_queue_init (avctx
, &ctx
->queue
);
499 if (decklink_start_input (avctx
) != S_OK
) {
500 av_log(avctx
, AV_LOG_ERROR
, "Cannot start input stream\n");
514 int ff_decklink_read_packet(AVFormatContext
*avctx
, AVPacket
*pkt
)
516 struct decklink_cctx
*cctx
= (struct decklink_cctx
*) avctx
->priv_data
;
517 struct decklink_ctx
*ctx
= (struct decklink_ctx
*) cctx
->ctx
;
518 AVFrame
*frame
= ctx
->video_st
->codec
->coded_frame
;
520 avpacket_queue_get(&ctx
->queue
, pkt
, 1);
521 if (frame
&& (ctx
->bmd_field_dominance
== bmdUpperFieldFirst
|| ctx
->bmd_field_dominance
== bmdLowerFieldFirst
)) {
522 frame
->interlaced_frame
= 1;
523 if (ctx
->bmd_field_dominance
== bmdUpperFieldFirst
) {
524 frame
->top_field_first
= 1;