[FFmpeg-devel] [PATCH 2/2] lavd: add decklink output device

Michael Niedermayer michaelni at gmx.at
Sun Feb 9 17:11:59 CET 2014


On Sat, Feb 08, 2014 at 11:09:18PM -0200, Ramiro Polla wrote:
> 2014-02-08 21:38 GMT-02:00 Michael Niedermayer <michaelni at gmx.at>:
> > On Sat, Feb 08, 2014 at 06:05:43PM -0200, Ramiro Polla wrote:
> >> 2014-01-13 21:08 GMT-02:00 Reimar Döffinger <Reimar.Doeffinger at gmx.de>:
> >> > On 13.01.2014, at 04:22, Ramiro Polla <ramiro.polla at gmail.com> wrote:
> >> >> On Sat, Dec 28, 2013 at 6:31 PM, Reimar Döffinger
> >> >> <Reimar.Doeffinger at gmx.de> wrote:
> >> >>> On Sat, Dec 28, 2013 at 05:06:16PM -0200, Ramiro Polla wrote:
> >> >>>> Hi Reimar,
> >> >>>>
> >> >>>> On Sat, Dec 28, 2013 at 1:23 PM, Reimar Döffinger
> >> >>>> <Reimar.Doeffinger at gmx.de> wrote:
> >> >>>>> On 26.12.2013, at 02:44, Ramiro Polla <ramiro.polla at gmail.com> wrote:
> >> >>>>>> Attached patch adds decklink output support to lavd. Works under Linux
> >> >>>>>> and Windows.
> >> >>>>>
> >> >>>>> Maybe a bit crazy, but how about splitting the C++ part out even more?
> >> >>>>> So that we can use designated initializers like for all other demuxers.
> >> >>>>> Otherwise it will break as soon as we add a new field in the middle, and in addition unless you add FATE testing that works without the hardware/library "nobody" will even notice.
> >> >>>>
> >> >>>> I thought about so too. On Windows it is possible to use COBJMACROS
> >> >>>> and write the code in C. But for Linux only a C++ interface is
> >> >>>> provided. What do you think about putting just the AVOption, AVClass
> >> >>>> and AVOutputFormat in a C file?
> >> >>>
> >> >>> Yes, either that or basically do a C++-to-C wrapper for the library.
> >> >>> I guess both will look quite similar.
> >> >>> As said, not sure if it's really worth it, but it _sounds_ better so
> >> >>> far.
> >> >>
> >> >> In ff_decklink_muxer, there's a sizeof(struct decklink_ctx), which
> >> >> contains a class* inside it. So that has to be c++ unless we make some
> >> >> hacks using void* or somesuch. Ideas?
> >> >
> >> > Void * should work fine.
> >> > You can also use an opaque struct decklink_stuff that is only fully declared in the C++ part and contains all the classes.
> >> > Means an additional allocation and deallocation for that sub-part though.
> >>
> >> It turns out the decklink headers are only half smart when dealing
> >> with C code (some are extern'd, some are not). New attached patch
> >> splits into C and C++ files with extra decklink context struct.
> >
> > [...]
> >> +static int decklink_setup_audio(AVFormatContext *avctx, AVStream *st)
> >> +{
> >> +    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
> >> +    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
> >> +    AVCodecContext *c = st->codec;
> >> +
> >> +    if (ctx->audio) {
> >> +        av_log(avctx, AV_LOG_ERROR, "Only one audio stream is supported!\n");
> >> +        return 0;
> >> +    }
> >> +    if (c->sample_rate != 48000) {
> >> +        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate!"
> >> +               " Only 48kHz is supported.\n");
> >> +        return 0;
> >> +    }
> >> +    if (c->channels != 2 && c->channels != 8) {
> >> +        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels!"
> >> +               " Only stereo and 7.1 are supported.\n");
> >> +        return 0;
> >> +    }
> >> +    if (ctx->dlo->EnableAudioOutput(bmdAudioSampleRate48kHz,
> >> +                                    bmdAudioSampleType16bitInteger,
> >> +                                    c->channels,
> >> +                                    bmdAudioOutputStreamTimestamped) != S_OK) {
> >> +        av_log(avctx, AV_LOG_ERROR, "Could not enable audio output!\n");
> >> +        return 0;
> >> +    }
> >> +    if (ctx->dlo->BeginAudioPreroll() != S_OK) {
> >> +        av_log(avctx, AV_LOG_ERROR, "Could not begin audio preroll!\n");
> >> +        return 0;
> >> +    }
> >> +
> >> +    /* The device expects the sample rate to be fixed. */
> >> +    avpriv_set_pts_info(st, 64, 1, c->sample_rate);
> >> +    ctx->channels = c->channels;
> >> +
> >> +    ctx->audio = 1;
> >> +
> >> +    return 1;
> >> +}
> >> +
> >> +av_cold int ff_decklink_write_trailer(AVFormatContext *avctx)
> >> +{
> >> +    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
> >> +    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
> >> +
> >> +    if (ctx->playback_started) {
> >> +        BMDTimeValue actual;
> >> +        ctx->dlo->StopScheduledPlayback(ctx->last_pts * ctx->bmd_tb_num,
> >> +                                        &actual, ctx->bmd_tb_den);
> >> +        ctx->dlo->DisableVideoOutput();
> >> +        if (ctx->audio)
> >> +            ctx->dlo->DisableAudioOutput();
> >> +    }
> >> +
> >> +    if (ctx->dlo)
> >> +        ctx->dlo->Release();
> >> +    if (ctx->dl)
> >> +        ctx->dl->Release();
> >> +
> >> +    if (ctx->callback)
> >> +        delete ctx->callback;
> >> +
> >> +    sem_destroy(&ctx->semaphore);
> >> +
> >> +    av_freep(&cctx->ctx);
> >> +
> >> +    return 0;
> >> +}
> >
> > the return codes are inconsistent, this uses 0 like most of ffmpeg
> > as "success" while the one aboce uses 1
> > I think that could confuse a reader easily
> >
> >
> >
> > [...]
> >> +int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt)
> >> +{
> >> +    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
> >> +    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
> >> +    AVStream *st = avctx->streams[pkt->stream_index];
> >> +
> >
> >> +    if (ctx->last_pts < pkt->pts)
> >> +        ctx->last_pts = pkt->pts;
> >
> > FFMAX()
> >
> >
> > [...]
> >> diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c
> >> new file mode 100644
> >> index 0000000..be4c90d
> >> --- /dev/null
> >> +++ b/libavdevice/decklink_enc_c.c
> >> @@ -0,0 +1,55 @@
> >> +/*
> >> + * Blackmagic DeckLink output
> >> + * Copyright (c) 2013-2014 Ramiro Polla
> >> + *
> >> + * This file is part of FFmpeg.
> >> + *
> >> + * FFmpeg is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU Lesser General Public
> >> + * License as published by the Free Software Foundation; either
> >> + * version 2.1 of the License, or (at your option) any later version.
> >> + *
> >> + * FFmpeg is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> + * Lesser General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU Lesser General Public
> >> + * License along with FFmpeg; if not, write to the Free Software
> >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> >> + */
> >> +
> >> +#include "libavformat/avformat.h"
> >> +#include "libavutil/opt.h"
> >> +
> >> +#include "decklink_enc.h"
> >> +
> >> +#define OFFSET(x) offsetof(struct decklink_cctx, x)
> >> +#define ENC AV_OPT_FLAG_ENCODING_PARAM
> >> +static const AVOption options[] = {
> >
> >> +    { "list_devices", "list available devices"  , OFFSET(list_devices), AV_OPT_TYPE_INT   , {        0   }, 0, 1, ENC },
> >> +    { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , {        0   }, 0, 1, ENC },
> >
> > probably makes no difference but .i64 = 0
> 
> Updated.

>  configure                    |    5 
>  doc/outdevs.texi             |   62 ++++
>  libavdevice/Makefile         |    1 
>  libavdevice/alldevices.c     |    1 
>  libavdevice/decklink_enc.cpp |  588 +++++++++++++++++++++++++++++++++++++++++++
>  libavdevice/decklink_enc.h   |   43 +++
>  libavdevice/decklink_enc_c.c |   55 ++++
>  libavdevice/version.h        |    2 
>  8 files changed, 756 insertions(+), 1 deletion(-)
> ceea7ba5fb70c821e446a5c1ab3f1abe8cd67636  0001-lavd-add-decklink-output-device.patch
> From 22b08fd0b8b7d8e81565c488e899bd7fce9492ca Mon Sep 17 00:00:00 2001
> From: Ramiro Polla <ramiro.polla at gmail.com>
> Date: Sat, 8 Feb 2014 18:01:26 -0200
> Subject: [PATCH] lavd: add decklink output device

applied

thanks

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The worst form of inequality is to try to make unequal things equal.
-- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140209/009a0b92/attachment.asc>


More information about the ffmpeg-devel mailing list