FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
decklink_enc.cpp
Go to the documentation of this file.
1 /*
2  * Blackmagic DeckLink output
3  * Copyright (c) 2013-2014 Ramiro Polla
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 <atomic>
23 using std::atomic;
24 
25 #include <DeckLinkAPI.h>
26 
27 #include <pthread.h>
28 #include <semaphore.h>
29 
30 extern "C" {
31 #include "libavformat/avformat.h"
32 #include "libavformat/internal.h"
33 #include "libavutil/imgutils.h"
34 }
35 
36 #include "decklink_common.h"
37 #include "decklink_enc.h"
38 
39 
40 /* DeckLink callback class declaration */
41 class decklink_frame : public IDeckLinkVideoFrame
42 {
43 public:
44  decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe) :
45  _ctx(ctx), _avframe(avframe), _refs(1) { }
46 
47  virtual long STDMETHODCALLTYPE GetWidth (void) { return _avframe->width; }
48  virtual long STDMETHODCALLTYPE GetHeight (void) { return _avframe->height; }
49  virtual long STDMETHODCALLTYPE GetRowBytes (void) { return _avframe->linesize[0] < 0 ? -_avframe->linesize[0] : _avframe->linesize[0]; }
50  virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void) { return bmdFormat8BitYUV; }
51  virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) { return _avframe->linesize[0] < 0 ? bmdFrameFlagFlipVertical : bmdFrameFlagDefault; }
52  virtual HRESULT STDMETHODCALLTYPE GetBytes (void **buffer)
53  {
54  if (_avframe->linesize[0] < 0)
55  *buffer = (void *)(_avframe->data[0] + _avframe->linesize[0] * (_avframe->height - 1));
56  else
57  *buffer = (void *)(_avframe->data[0]);
58  return S_OK;
59  }
60 
61  virtual HRESULT STDMETHODCALLTYPE GetTimecode (BMDTimecodeFormat format, IDeckLinkTimecode **timecode) { return S_FALSE; }
62  virtual HRESULT STDMETHODCALLTYPE GetAncillaryData(IDeckLinkVideoFrameAncillary **ancillary) { return S_FALSE; }
63 
64  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
65  virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++_refs; }
66  virtual ULONG STDMETHODCALLTYPE Release(void)
67  {
68  int ret = --_refs;
69  if (!ret) {
71  delete this;
72  }
73  return ret;
74  }
75 
76  struct decklink_ctx *_ctx;
78 
79 private:
80  std::atomic<int> _refs;
81 };
82 
83 class decklink_output_callback : public IDeckLinkVideoOutputCallback
84 {
85 public:
86  virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame *_frame, BMDOutputFrameCompletionResult result)
87  {
88  decklink_frame *frame = static_cast<decklink_frame *>(_frame);
89  struct decklink_ctx *ctx = frame->_ctx;
90  AVFrame *avframe = frame->_avframe;
91 
92  av_frame_unref(avframe);
93 
94  sem_post(&ctx->semaphore);
95 
96  return S_OK;
97  }
98  virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped(void) { return S_OK; }
99  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
100  virtual ULONG STDMETHODCALLTYPE AddRef(void) { return 1; }
101  virtual ULONG STDMETHODCALLTYPE Release(void) { return 1; }
102 };
103 
105 {
106  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
107  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
109 
110  if (ctx->video) {
111  av_log(avctx, AV_LOG_ERROR, "Only one video stream is supported!\n");
112  return -1;
113  }
114 
115  if (c->format != AV_PIX_FMT_UYVY422) {
116  av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format!"
117  " Only AV_PIX_FMT_UYVY422 is supported.\n");
118  return -1;
119  }
120  if (ff_decklink_set_format(avctx, c->width, c->height,
121  st->time_base.num, st->time_base.den, c->field_order)) {
122  av_log(avctx, AV_LOG_ERROR, "Unsupported video size, framerate or field order!"
123  " Check available formats with -list_formats 1.\n");
124  return -1;
125  }
126  if (ctx->dlo->EnableVideoOutput(ctx->bmd_mode,
127  bmdVideoOutputFlagDefault) != S_OK) {
128  av_log(avctx, AV_LOG_ERROR, "Could not enable video output!\n");
129  return -1;
130  }
131 
132  /* Set callback. */
133  ctx->output_callback = new decklink_output_callback();
134  ctx->dlo->SetScheduledFrameCompletionCallback(ctx->output_callback);
135 
136  /* Start video semaphore. */
137  ctx->frames_preroll = st->time_base.den * ctx->preroll;
138  if (st->time_base.den > 1000)
139  ctx->frames_preroll /= 1000;
140 
141  /* Buffer twice as many frames as the preroll. */
142  ctx->frames_buffer = ctx->frames_preroll * 2;
143  ctx->frames_buffer = FFMIN(ctx->frames_buffer, 60);
144  sem_init(&ctx->semaphore, 0, ctx->frames_buffer);
145 
146  /* The device expects the framerate to be fixed. */
147  avpriv_set_pts_info(st, 64, st->time_base.num, st->time_base.den);
148 
149  ctx->video = 1;
150 
151  return 0;
152 }
153 
155 {
156  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
157  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
159 
160  if (ctx->audio) {
161  av_log(avctx, AV_LOG_ERROR, "Only one audio stream is supported!\n");
162  return -1;
163  }
164  if (c->sample_rate != 48000) {
165  av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate!"
166  " Only 48kHz is supported.\n");
167  return -1;
168  }
169  if (c->channels != 2 && c->channels != 8) {
170  av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels!"
171  " Only stereo and 7.1 are supported.\n");
172  return -1;
173  }
174  if (ctx->dlo->EnableAudioOutput(bmdAudioSampleRate48kHz,
175  bmdAudioSampleType16bitInteger,
176  c->channels,
177  bmdAudioOutputStreamTimestamped) != S_OK) {
178  av_log(avctx, AV_LOG_ERROR, "Could not enable audio output!\n");
179  return -1;
180  }
181  if (ctx->dlo->BeginAudioPreroll() != S_OK) {
182  av_log(avctx, AV_LOG_ERROR, "Could not begin audio preroll!\n");
183  return -1;
184  }
185 
186  /* The device expects the sample rate to be fixed. */
187  avpriv_set_pts_info(st, 64, 1, c->sample_rate);
188  ctx->channels = c->channels;
189 
190  ctx->audio = 1;
191 
192  return 0;
193 }
194 
196 {
197  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
198  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
199 
200  if (ctx->playback_started) {
201  BMDTimeValue actual;
202  ctx->dlo->StopScheduledPlayback(ctx->last_pts * ctx->bmd_tb_num,
203  &actual, ctx->bmd_tb_den);
204  ctx->dlo->DisableVideoOutput();
205  if (ctx->audio)
206  ctx->dlo->DisableAudioOutput();
207  }
208 
209  ff_decklink_cleanup(avctx);
210 
211  if (ctx->output_callback)
212  delete ctx->output_callback;
213 
214  sem_destroy(&ctx->semaphore);
215 
216  av_freep(&cctx->ctx);
217 
218  return 0;
219 }
220 
222 {
223  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
224  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
225  AVFrame *avframe, *tmp = (AVFrame *)pkt->data;
227  buffercount_type buffered;
228  HRESULT hr;
229 
230  if (tmp->format != AV_PIX_FMT_UYVY422 ||
231  tmp->width != ctx->bmd_width ||
232  tmp->height != ctx->bmd_height) {
233  av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format or dimension.\n");
234  return AVERROR(EINVAL);
235  }
236  avframe = av_frame_clone(tmp);
237  if (!avframe) {
238  av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n");
239  return AVERROR(EIO);
240  }
241 
242  frame = new decklink_frame(ctx, avframe);
243  if (!frame) {
244  av_log(avctx, AV_LOG_ERROR, "Could not create new frame.\n");
245  av_frame_free(&avframe);
246  return AVERROR(EIO);
247  }
248 
249  /* Always keep at most one second of frames buffered. */
250  sem_wait(&ctx->semaphore);
251 
252  /* Schedule frame for playback. */
253  hr = ctx->dlo->ScheduleVideoFrame((struct IDeckLinkVideoFrame *) frame,
254  pkt->pts * ctx->bmd_tb_num,
255  ctx->bmd_tb_num, ctx->bmd_tb_den);
256  /* Pass ownership to DeckLink, or release on failure */
257  frame->Release();
258  if (hr != S_OK) {
259  av_log(avctx, AV_LOG_ERROR, "Could not schedule video frame."
260  " error %08x.\n", (uint32_t) hr);
261  return AVERROR(EIO);
262  }
263 
264  ctx->dlo->GetBufferedVideoFrameCount(&buffered);
265  av_log(avctx, AV_LOG_DEBUG, "Buffered video frames: %d.\n", (int) buffered);
266  if (pkt->pts > 2 && buffered <= 2)
267  av_log(avctx, AV_LOG_WARNING, "There are not enough buffered video frames."
268  " Video may misbehave!\n");
269 
270  /* Preroll video frames. */
271  if (!ctx->playback_started && pkt->pts > ctx->frames_preroll) {
272  av_log(avctx, AV_LOG_DEBUG, "Ending audio preroll.\n");
273  if (ctx->audio && ctx->dlo->EndAudioPreroll() != S_OK) {
274  av_log(avctx, AV_LOG_ERROR, "Could not end audio preroll!\n");
275  return AVERROR(EIO);
276  }
277  av_log(avctx, AV_LOG_DEBUG, "Starting scheduled playback.\n");
278  if (ctx->dlo->StartScheduledPlayback(0, ctx->bmd_tb_den, 1.0) != S_OK) {
279  av_log(avctx, AV_LOG_ERROR, "Could not start scheduled playback!\n");
280  return AVERROR(EIO);
281  }
282  ctx->playback_started = 1;
283  }
284 
285  return 0;
286 }
287 
289 {
290  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
291  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
292  int sample_count = pkt->size / (ctx->channels << 1);
293  buffercount_type buffered;
294 
295  ctx->dlo->GetBufferedAudioSampleFrameCount(&buffered);
296  if (pkt->pts > 1 && !buffered)
297  av_log(avctx, AV_LOG_WARNING, "There's no buffered audio."
298  " Audio will misbehave!\n");
299 
300  if (ctx->dlo->ScheduleAudioSamples(pkt->data, sample_count, pkt->pts,
301  bmdAudioSampleRate48kHz, NULL) != S_OK) {
302  av_log(avctx, AV_LOG_ERROR, "Could not schedule audio samples.\n");
303  return AVERROR(EIO);
304  }
305 
306  return 0;
307 }
308 
309 extern "C" {
310 
312 {
313  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
314  struct decklink_ctx *ctx;
315  unsigned int n;
316  int ret;
317 
318  ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
319  if (!ctx)
320  return AVERROR(ENOMEM);
321  ctx->list_devices = cctx->list_devices;
322  ctx->list_formats = cctx->list_formats;
323  ctx->preroll = cctx->preroll;
324  cctx->ctx = ctx;
325 
326  /* List available devices. */
327  if (ctx->list_devices) {
329  return AVERROR_EXIT;
330  }
331 
332  ret = ff_decklink_init_device(avctx, avctx->filename);
333  if (ret < 0)
334  return ret;
335 
336  /* Get output device. */
337  if (ctx->dl->QueryInterface(IID_IDeckLinkOutput, (void **) &ctx->dlo) != S_OK) {
338  av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
339  avctx->filename);
340  ret = AVERROR(EIO);
341  goto error;
342  }
343 
344  /* List supported formats. */
345  if (ctx->list_formats) {
347  ret = AVERROR_EXIT;
348  goto error;
349  }
350 
351  /* Setup streams. */
352  ret = AVERROR(EIO);
353  for (n = 0; n < avctx->nb_streams; n++) {
354  AVStream *st = avctx->streams[n];
356  if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
357  if (decklink_setup_audio(avctx, st))
358  goto error;
359  } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) {
360  if (decklink_setup_video(avctx, st))
361  goto error;
362  } else {
363  av_log(avctx, AV_LOG_ERROR, "Unsupported stream type.\n");
364  goto error;
365  }
366  }
367 
368  return 0;
369 
370 error:
371  ff_decklink_cleanup(avctx);
372  return ret;
373 }
374 
376 {
377  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
378  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
379  AVStream *st = avctx->streams[pkt->stream_index];
380 
381  ctx->last_pts = FFMAX(ctx->last_pts, pkt->pts);
382 
384  return decklink_write_video_packet(avctx, pkt);
385  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
386  return decklink_write_audio_packet(avctx, pkt);
387 
388  return AVERROR(EIO);
389 }
390 
391 } /* extern "C" */
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:82
#define NULL
Definition: coverity.c:32
enum AVFieldOrder field_order
Video only.
Definition: avcodec.h:4147
#define S_OK
Definition: windows2linux.h:40
This structure describes decoded (raw) audio or video data.
Definition: frame.h:187
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:4601
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1658
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:222
static AVPacket pkt
This struct describes the properties of an encoded stream.
Definition: avcodec.h:4058
Format I/O context.
Definition: avformat.h:1349
#define av_cold
Definition: attributes.h:82
int width
Video only.
Definition: avcodec.h:4132
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1417
static AVFrame * frame
#define sem_init
Definition: semaphore.h:40
uint8_t * data
Definition: avcodec.h:1657
#define E_NOINTERFACE
Definition: windows2linux.h:42
#define sem_post(psem)
Definition: semaphore.h:26
#define av_log(a,...)
int width
width and height of the video frame
Definition: frame.h:239
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:163
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:4062
#define sem_destroy(psem)
Definition: semaphore.h:29
#define FFMAX(a, b)
Definition: common.h:94
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1405
char filename[1024]
input or output filename
Definition: avformat.h:1425
#define FFMIN(a, b)
Definition: common.h:96
AVFormatContext * ctx
Definition: movenc.c:48
int n
Definition: avisynth_c.h:684
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
static void error(const char *err)
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:485
Stream structure.
Definition: avformat.h:889
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:251
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:218
void * LPVOID
static const char * format
Definition: movenc.c:47
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:498
DWORD HRESULT
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:201
int sample_rate
Audio only.
Definition: avcodec.h:4176
Main libavformat public API header.
if(ret< 0)
Definition: vf_mcdeint.c:282
static double c[64]
uint32_t ULONG
int den
Denominator.
Definition: rational.h:60
#define S_FALSE
Definition: windows2linux.h:41
void * priv_data
Format private data.
Definition: avformat.h:1377
#define sem_wait(psem)
Definition: semaphore.h:27
int channels
Audio only.
Definition: avcodec.h:4172
int height
Definition: frame.h:239
#define av_freep(p)
AVCodecParameters * codecpar
Definition: avformat.h:1252
int stream_index
Definition: avcodec.h:1659
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:926
This structure stores compressed data.
Definition: avcodec.h:1634
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1650
GLuint buffer
Definition: opengl_enc.c:102
static uint8_t tmp[11]
Definition: aes_ctr.c:26