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

Michael Niedermayer michaelni at gmx.at
Sun Feb 9 00:38:25 CET 2014


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

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

During times of universal deceit, telling the truth becomes a
revolutionary act. -- George Orwell
-------------- 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/bc240d90/attachment.asc>


More information about the ffmpeg-devel mailing list