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));
39  pthread_mutex_init(&q->mutex, NULL);
40  pthread_cond_init(&q->cond, NULL);
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;
175  pthread_mutex_init(&m_mutex, NULL);
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  unsigned bars[8] = {
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;
242 
243  for (int y = 0; y < height; y++) {
244  for (int x = 0; x < width; x += 2)
245  *p++ = bars[(x * 8) / width];
246  }
247 
248  if (!no_video) {
249  av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - No input signal detected "
250  "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
251  }
252  no_video = 1;
253  } else {
254  if (no_video) {
255  av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - Input returned "
256  "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
257  }
258  no_video = 0;
259  }
260 
261  pkt.pts = frameTime / ctx->video_st->time_base.num;
262 
264  initial_video_pts = pkt.pts;
265  }
266 
267  pkt.pts -= initial_video_pts;
268  pkt.dts = pkt.pts;
269 
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);
278  c->frame_number++;
279  if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
280  ++ctx->dropped;
281  }
282  }
283 
284  // Handle Audio Frame
285  if (audioFrame) {
286  AVCodecContext *c;
287  AVPacket pkt;
288  BMDTimeValue audio_pts;
289  av_init_packet(&pkt);
290 
291  c = ctx->audio_st->codec;
292  //hack among hacks
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;
297 
299  initial_audio_pts = pkt.pts;
300  }
301 
302  pkt.pts -= initial_audio_pts;
303  pkt.dts = pkt.pts;
304 
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;
309 
310  c->frame_number++;
311  if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
312  ++ctx->dropped;
313  }
314  }
315 
316  return S_OK;
317 }
318 
320  BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
321  BMDDetectedVideoInputFormatFlags)
322 {
323  return S_OK;
324 }
325 
327 {
328  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
329  struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
330 
331  ctx->input_callback = new decklink_input_callback(avctx);
332  ctx->dli->SetCallback(ctx->input_callback);
333  return ctx->dli->StartStreams();
334 }
335 
336 extern "C" {
337 
339 {
340  struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
341  struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
342 
343  if (ctx->capture_started) {
344  ctx->dli->StopStreams();
345  ctx->dli->DisableVideoInput();
346  ctx->dli->DisableAudioInput();
347  }
348 
349  if (ctx->dli)
350  ctx->dli->Release();
351  if (ctx->dl)
352  ctx->dl->Release();
353 
354  avpacket_queue_end(&ctx->queue);
355 
356  av_freep(&cctx->ctx);
357 
358  return 0;
359 }
360 
362 {
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;
368  AVStream *st;
369  HRESULT result;
370  char fname[1024];
371  char *tmp;
372  int mode_num = 0;
373 
374  ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
375  if (!ctx)
376  return AVERROR(ENOMEM);
377  ctx->list_devices = cctx->list_devices;
378  ctx->list_formats = cctx->list_formats;
379  ctx->preroll = cctx->preroll;
380  cctx->ctx = ctx;
381 
382  iter = CreateDeckLinkIteratorInstance();
383  if (!iter) {
384  av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
385  return AVERROR(EIO);
386  }
387 
388  /* List available devices. */
389  if (ctx->list_devices) {
391  return AVERROR_EXIT;
392  }
393 
394  strcpy (fname, avctx->filename);
395  tmp=strchr (fname, '@');
396  if (tmp != NULL) {
397  mode_num = atoi (tmp+1);
398  *tmp = 0;
399  }
400 
401  /* Open device. */
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);
407  ctx->dl = dl;
408  break;
409  }
410  av_free((void *) displayName);
411  dl->Release();
412  }
413  iter->Release();
414  if (!ctx->dl) {
415  av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", fname);
416  return AVERROR(EIO);
417  }
418 
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",
422  avctx->filename);
423  ctx->dl->Release();
424  return AVERROR(EIO);
425  }
426 
427  /* List supported formats. */
428  if (ctx->list_formats) {
430  ctx->dli->Release();
431  ctx->dl->Release();
432  return AVERROR_EXIT;
433  }
434 
435  if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) {
436  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
437  ctx->dl->Release();
438  return AVERROR(EIO);
439  }
440 
441  if (mode_num > 0) {
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);
444  goto error;
445  }
446  }
447 
448  itermode->Release();
449 
450  /* Setup streams. */
451  st = avformat_new_stream(avctx, NULL);
452  if (!st) {
453  av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
454  goto error;
455  }
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 */
461  ctx->audio_st=st;
462 
463  st = avformat_new_stream(avctx, NULL);
464  if (!st) {
465  av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
466  goto error;
467  }
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;
472 
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');
478 
479  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
480 
481  ctx->video_st=st;
482 
483  result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);
484 
485  if (result != S_OK) {
486  av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
487  goto error;
488  }
489 
490  result = ctx->dli->EnableVideoInput(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoInputFlagDefault);
491 
492  if (result != S_OK) {
493  av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");
494  goto error;
495  }
496 
497  avpacket_queue_init (avctx, &ctx->queue);
498 
499  if (decklink_start_input (avctx) != S_OK) {
500  av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
501  goto error;
502  }
503 
504  return 0;
505 
506 error:
507 
508  ctx->dli->Release();
509  ctx->dl->Release();
510 
511  return AVERROR(EIO);
512 }
513 
515 {
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;
519 
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;
525  }
526  }
527 
528  return 0;
529 }
530 
531 } /* extern "C" */