FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
decklink_dec.cpp
Go to the documentation of this file.
1 /*
2  * Blackmagic DeckLink output
3  * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #include <DeckLinkAPI.h>
23 
24 #include <pthread.h>
25 #include <semaphore.h>
26 
27 extern "C" {
28 #include "libavformat/avformat.h"
29 #include "libavformat/internal.h"
30 #include "libavutil/imgutils.h"
31 }
32 
33 #include "decklink_common.h"
34 #include "decklink_dec.h"
35 
37 {
38  memset(q, 0, sizeof(AVPacketQueue));
41  q->avctx = avctx;
42 }
43 
45 {
46  AVPacketList *pkt, *pkt1;
47 
49  for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
50  pkt1 = pkt->next;
51  av_free_packet(&pkt->pkt);
52  av_freep(&pkt);
53  }
54  q->last_pkt = NULL;
55  q->first_pkt = NULL;
56  q->nb_packets = 0;
57  q->size = 0;
59 }
60 
62 {
66 }
67 
68 static unsigned long long avpacket_queue_size(AVPacketQueue *q)
69 {
70  unsigned long long size;
72  size = q->size;
74  return size;
75 }
76 
78 {
79  AVPacketList *pkt1;
80 
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");
84  return -1;
85  }
86  /* duplicate the packet */
87  if (av_dup_packet(pkt) < 0) {
88  return -1;
89  }
90 
91  pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList));
92  if (!pkt1) {
93  return -1;
94  }
95  pkt1->pkt = *pkt;
96  pkt1->next = NULL;
97 
99 
100  if (!q->last_pkt) {
101  q->first_pkt = pkt1;
102  } else {
103  q->last_pkt->next = pkt1;
104  }
105 
106  q->last_pkt = pkt1;
107  q->nb_packets++;
108  q->size += pkt1->pkt.size + sizeof(*pkt1);
109 
111 
113  return 0;
114 }
115 
117 {
118  AVPacketList *pkt1;
119  int ret;
120 
122 
123  for (;; ) {
124  pkt1 = q->first_pkt;
125  if (pkt1) {
126  q->first_pkt = pkt1->next;
127  if (!q->first_pkt) {
128  q->last_pkt = NULL;
129  }
130  q->nb_packets--;
131  q->size -= pkt1->pkt.size + sizeof(*pkt1);
132  *pkt = pkt1->pkt;
133  av_free(pkt1);
134  ret = 1;
135  break;
136  } else if (!block) {
137  ret = 0;
138  break;
139  } else {
140  pthread_cond_wait(&q->cond, &q->mutex);
141  }
142  }
144  return ret;
145 }
146 
147 class decklink_input_callback : public IDeckLinkInputCallback
148 {
149 public:
152 
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*);
158 
159 private:
164  int no_video;
167 };
168 
170 {
171  avctx = _avctx;
172  decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
173  ctx = (struct decklink_ctx *) cctx->ctx;
176 }
177 
179 {
181 }
182 
184 {
186  m_refCount++;
188 
189  return (ULONG)m_refCount;
190 }
191 
193 {
195  m_refCount--;
197 
198  if (m_refCount == 0) {
199  delete this;
200  return 0;
201  }
202 
203  return (ULONG)m_refCount;
204 }
205 
207  IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame)
208 {
209  void *frameBytes;
210  void *audioFrameBytes;
211  BMDTimeValue frameTime;
212  BMDTimeValue frameDuration;
213 
214  ctx->frameCount++;
215 
216  // Handle Video Frame
217  if (videoFrame) {
218  AVPacket pkt;
219  AVCodecContext *c;
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);
225  "Frame received (#%lu) - Valid (%liB) - QSize %fMB\n",
226  ctx->frameCount,
227  videoFrame->GetRowBytes() * videoFrame->GetHeight(),
228  (double)qsize / 1024 / 1024);
229  }
230 
231  videoFrame->GetBytes(&frameBytes);
232  videoFrame->GetStreamTime(&frameTime, &frameDuration,
234 
235  if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
236  if (videoFrame->GetPixelFormat() == bmdFormat8BitYUV) {
237  unsigned bars[8] = {
238  0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
239  0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
240  int width = videoFrame->GetWidth();
241  int height = videoFrame->GetHeight();
242  unsigned *p = (unsigned *)frameBytes;
243 
244  for (int y = 0; y < height; y++) {
245  for (int x = 0; x < width; x += 2)
246  *p++ = bars[(x * 8) / width];
247  }
248  }
249 
250  if (!no_video) {
251  av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - No input signal detected "
252  "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
253  }
254  no_video = 1;
255  } else {
256  if (no_video) {
257  av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - Input returned "
258  "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
259  }
260  no_video = 0;
261  }
262 
263  pkt.pts = frameTime / ctx->video_st->time_base.num;
264 
266  initial_video_pts = pkt.pts;
267  }
268 
269  pkt.pts -= initial_video_pts;
270  pkt.dts = pkt.pts;
271 
272  pkt.duration = frameDuration;
273  //To be made sure it still applies
274  pkt.flags |= AV_PKT_FLAG_KEY;
275  pkt.stream_index = ctx->video_st->index;
276  pkt.data = (uint8_t *)frameBytes;
277  pkt.size = videoFrame->GetRowBytes() *
278  videoFrame->GetHeight();
279  //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);
280  c->frame_number++;
281  if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
282  ++ctx->dropped;
283  }
284  }
285 
286  // Handle Audio Frame
287  if (audioFrame) {
288  AVCodecContext *c;
289  AVPacket pkt;
290  BMDTimeValue audio_pts;
291  av_init_packet(&pkt);
292 
293  c = ctx->audio_st->codec;
294  //hack among hacks
295  pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codec->channels * (16 / 8);
296  audioFrame->GetBytes(&audioFrameBytes);
297  audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);
298  pkt.pts = audio_pts / ctx->audio_st->time_base.num;
299 
301  initial_audio_pts = pkt.pts;
302  }
303 
304  pkt.pts -= initial_audio_pts;
305  pkt.dts = pkt.pts;
306 
307  //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);
308  pkt.flags |= AV_PKT_FLAG_KEY;
309  pkt.stream_index = ctx->audio_st->index;
310  pkt.data = (uint8_t *)audioFrameBytes;
311 
312  c->frame_number++;
313  if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
314  ++ctx->dropped;
315  }
316  }
317 
318  return S_OK;
319 }
320 
322  BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
323  BMDDetectedVideoInputFormatFlags)
324 {
325  return S_OK;
326 }
327 
329 {
330  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
331  struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
332 
333  ctx->input_callback = new decklink_input_callback(avctx);
334  ctx->dli->SetCallback(ctx->input_callback);
335  return ctx->dli->StartStreams();
336 }
337 
338 extern "C" {
339 
341 {
342  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
343  struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
344 
345  if (ctx->capture_started) {
346  ctx->dli->StopStreams();
347  ctx->dli->DisableVideoInput();
348  ctx->dli->DisableAudioInput();
349  }
350 
351  if (ctx->dli)
352  ctx->dli->Release();
353  if (ctx->dl)
354  ctx->dl->Release();
355 
356  avpacket_queue_end(&ctx->queue);
357 
358  av_freep(&cctx->ctx);
359 
360  return 0;
361 }
362 
364 {
365  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
366  struct decklink_ctx *ctx;
367  IDeckLinkDisplayModeIterator *itermode;
368  IDeckLinkIterator *iter;
369  IDeckLink *dl = NULL;
370  AVStream *st;
371  HRESULT result;
372  char fname[1024];
373  char *tmp;
374  int mode_num = 0;
375 
376  ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
377  if (!ctx)
378  return AVERROR(ENOMEM);
379  ctx->list_devices = cctx->list_devices;
380  ctx->list_formats = cctx->list_formats;
381  ctx->preroll = cctx->preroll;
382  cctx->ctx = ctx;
383 
384  iter = CreateDeckLinkIteratorInstance();
385  if (!iter) {
386  av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
387  return AVERROR(EIO);
388  }
389 
390  /* List available devices. */
391  if (ctx->list_devices) {
393  return AVERROR_EXIT;
394  }
395 
396  strcpy (fname, avctx->filename);
397  tmp=strchr (fname, '@');
398  if (tmp != NULL) {
399  mode_num = atoi (tmp+1);
400  *tmp = 0;
401  }
402 
403  /* Open device. */
404  while (iter->Next(&dl) == S_OK) {
405  const char *displayName;
406  ff_decklink_get_display_name(dl, &displayName);
407  if (!strcmp(fname, displayName)) {
408  av_free((void *) displayName);
409  ctx->dl = dl;
410  break;
411  }
412  av_free((void *) displayName);
413  dl->Release();
414  }
415  iter->Release();
416  if (!ctx->dl) {
417  av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", fname);
418  return AVERROR(EIO);
419  }
420 
421  /* Get input device. */
422  if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) {
423  av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
424  avctx->filename);
425  ctx->dl->Release();
426  return AVERROR(EIO);
427  }
428 
429  /* List supported formats. */
430  if (ctx->list_formats) {
432  ctx->dli->Release();
433  ctx->dl->Release();
434  return AVERROR_EXIT;
435  }
436 
437  if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) {
438  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
439  ctx->dl->Release();
440  return AVERROR(EIO);
441  }
442 
443  if (mode_num > 0) {
444  if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
445  av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname);
446  goto error;
447  }
448  }
449 
450  itermode->Release();
451 
452  /* Setup streams. */
453  st = avformat_new_stream(avctx, NULL);
454  if (!st) {
455  av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
456  goto error;
457  }
458  st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
459  st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
460  st->codec->sample_rate = bmdAudioSampleRate48kHz;
461  st->codec->channels = 2;
462  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
463  ctx->audio_st=st;
464 
465  st = avformat_new_stream(avctx, NULL);
466  if (!st) {
467  av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
468  goto error;
469  }
470  st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
471  st->codec->width = ctx->bmd_width;
472  st->codec->height = ctx->bmd_height;
473 
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 
478  if (cctx->v210) {
479  st->codec->codec_id = AV_CODEC_ID_V210;
480  st->codec->codec_tag = MKTAG('V', '2', '1', '0');
481  } else {
482  st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
483  st->codec->pix_fmt = AV_PIX_FMT_UYVY422;
484  st->codec->codec_tag = MKTAG('U', 'Y', 'V', 'Y');
485  }
486 
487  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
488 
489  ctx->video_st=st;
490 
491  result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);
492 
493  if (result != S_OK) {
494  av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
495  goto error;
496  }
497 
498  result = ctx->dli->EnableVideoInput(ctx->bmd_mode,
499  cctx->v210 ? bmdFormat10BitYUV : bmdFormat8BitYUV,
500  bmdVideoInputFlagDefault);
501 
502  if (result != S_OK) {
503  av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");
504  goto error;
505  }
506 
507  avpacket_queue_init (avctx, &ctx->queue);
508 
509  if (decklink_start_input (avctx) != S_OK) {
510  av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
511  goto error;
512  }
513 
514  return 0;
515 
516 error:
517 
518  ctx->dli->Release();
519  ctx->dl->Release();
520 
521  return AVERROR(EIO);
522 }
523 
525 {
526  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
527  struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
528  AVFrame *frame = ctx->video_st->codec->coded_frame;
529 
530  avpacket_queue_get(&ctx->queue, pkt, 1);
531  if (frame && (ctx->bmd_field_dominance == bmdUpperFieldFirst || ctx->bmd_field_dominance == bmdLowerFieldFirst)) {
532  frame->interlaced_frame = 1;
533  if (ctx->bmd_field_dominance == bmdUpperFieldFirst) {
534  frame->top_field_first = 1;
535  }
536  }
537 
538  return 0;
539 }
540 
541 } /* extern "C" */
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:83
#define NULL
Definition: coverity.c:32
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:94
#define S_OK
Definition: windows2linux.h:40
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:280
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:153
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4006
int num
numerator
Definition: rational.h:44
int index
stream index in AVFormatContext
Definition: avformat.h:843
int size
Definition: avcodec.h:1163
static AVPacket pkt
int av_dup_packet(AVPacket *pkt)
Definition: avpacket.c:248
pthread_cond_t cond
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:124
Format I/O context.
Definition: avformat.h:1272
HMTX pthread_mutex_t
Definition: os2threads.h:40
uint8_t
#define av_cold
Definition: attributes.h:74
#define av_malloc(s)
pthread_mutex_t mutex
mode
Definition: f_perms.c:27
AVPacket pkt
Definition: avformat.h:1845
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:3672
static AVFrame * frame
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:80
uint8_t * data
Definition: avcodec.h:1162
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:131
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:367
ptrdiff_t size
Definition: opengl_enc.c:101
#define E_NOINTERFACE
Definition: windows2linux.h:42
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1180
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1208
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVPacketList * last_pkt
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1168
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:861
char filename[1024]
input or output filename
Definition: avformat.h:1348
float y
AVPacketList * first_pkt
unsigned long long size
ret
Definition: avfilter.c:974
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:87
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
Stream structure.
Definition: avformat.h:842
void * LPVOID
main external API structure.
Definition: avcodec.h:1241
BYTE int const BYTE int int int height
Definition: avisynth_c.h:676
AVFormatContext * avctx
DWORD HRESULT
Main libavformat public API header.
struct AVPacketList * next
Definition: avformat.h:1846
static double c[64]
uint32_t ULONG
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:115
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:49
int den
denominator
Definition: rational.h:45
#define av_free(p)
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:372
int channels
number of audio channels
Definition: avcodec.h:1986
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:108
void * priv_data
Format private data.
Definition: avformat.h:1300
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
Calculate the size in bytes that a picture of the given width and height would occupy if stored in th...
Definition: avpicture.c:49
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1161
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2016
#define av_freep(p)
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:101
int stream_index
Definition: avcodec.h:1164
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:884
#define MKTAG(a, b, c, d)
Definition: common.h:315
This structure stores compressed data.
Definition: avcodec.h:1139
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:250
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1155
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:241
static int width
static int16_t block[64]
Definition: dct-test.c:110