blob: 18ef9058e28c38752b1b9c2c39cdb0a6c08c8785
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) { |
70 | av_frame_free(&_avframe); |
71 | delete this; |
72 | } |
73 | return ret; |
74 | } |
75 | |
76 | struct decklink_ctx *_ctx; |
77 | AVFrame *_avframe; |
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 | |
104 | static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) |
105 | { |
106 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
107 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
108 | AVCodecParameters *c = st->codecpar; |
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 | |
154 | static int decklink_setup_audio(AVFormatContext *avctx, AVStream *st) |
155 | { |
156 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
157 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
158 | AVCodecParameters *c = st->codecpar; |
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 | |
195 | av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) |
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 | |
221 | static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) |
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; |
226 | decklink_frame *frame; |
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 | |
288 | static int decklink_write_audio_packet(AVFormatContext *avctx, AVPacket *pkt) |
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 | |
311 | av_cold int ff_decklink_write_header(AVFormatContext *avctx) |
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) { |
328 | ff_decklink_list_devices(avctx); |
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) { |
346 | ff_decklink_list_formats(avctx); |
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]; |
355 | AVCodecParameters *c = st->codecpar; |
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 | |
375 | int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt) |
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 | |
383 | if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) |
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" */ |
392 |