[FFmpeg-devel] [PATCH 02/11] decklink: Add support for output of Active Format Description (AFD)

Marton Balint cus at passwd.hu
Fri Jan 12 20:25:10 EET 2018



On Mon, 8 Jan 2018, Devin Heitmueller wrote:

> Implement support for including AFD in decklink output.  This
> includes making sure the AFD data is preserved when going from
> an AVFrame to a V210 packet (needed for 10-bit support).
>
> Updated to reflect feedback from Marton Balint <cus at passwd.hu>,
> Carl Eugen Hoyos <ceffmpeg at gmail.com> and Aaron Levinson
> <alevinsn_dev at levland.net>.
>
> Signed-off-by: Devin Heitmueller <dheitmueller at ltnglobal.com>
> ---
> libavcodec/avcodec.h         |  6 ++++++
> libavcodec/v210enc.c         |  8 ++++++++
> libavdevice/decklink_enc.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 56 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index c13deb5..5fa028e 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -1342,6 +1342,12 @@ enum AVPacketSideDataType {
>     AV_PKT_DATA_A53_CC,
>
>     /**
> +     * Active Format Description data consisting of a single byte as specified
> +     * in ETSI TS 101 154 using AVActiveFormatDescription enum.
> +     */
> +    AV_PKT_DATA_AFD,
> +
> +    /**
>      * The number of side data types.
>      * This is not part of the public API/ABI in the sense that it may
>      * change when new side data types are added.
> diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
> index b9dcf9a..b024806 100644
> --- a/libavcodec/v210enc.c
> +++ b/libavcodec/v210enc.c
> @@ -242,6 +242,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
>         memcpy(buf, side_data->data, side_data->size);
>     }
> 
> +    side_data = av_frame_get_side_data(pic, AV_FRAME_DATA_AFD);
> +    if (side_data && side_data->size) {
> +        uint8_t *buf = av_packet_new_side_data(pkt, AV_PKT_DATA_AFD, side_data->size);
> +        if (!buf)
> +            return AVERROR(ENOMEM);
> +        memcpy(buf, side_data->data, side_data->size);
> +    }
> +
>     pkt->flags |= AV_PKT_FLAG_KEY;
>     *got_packet = 1;
>     return 0;
> diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp
> index faa382a..ff60050 100644
> --- a/libavdevice/decklink_enc.cpp
> +++ b/libavdevice/decklink_enc.cpp
> @@ -301,7 +301,8 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx)
> 
> #if CONFIG_LIBKLVANC
> static int decklink_construct_vanc(AVFormatContext *avctx, struct decklink_ctx *ctx,
> -                                   AVPacket *pkt, decklink_frame *frame)
> +                                   AVPacket *pkt, decklink_frame *frame,
> +                                   AVStream *st)
> {
>     struct klvanc_line_set_s vanc_lines = { 0 };
>     int ret, size;
> @@ -359,6 +360,45 @@ static int decklink_construct_vanc(AVFormatContext *avctx, struct decklink_ctx *
>         }
>     }
>

In all the error handling below, vanc_lines might need a free, because it 
might already contain buffers with a53 data, no?

> +    data = av_packet_get_side_data(pkt, AV_PKT_DATA_AFD, &size);
> +    if (data) {
> +        struct klvanc_packet_afd_s *pkt;
> +        uint16_t *afd;
> +        uint16_t len;
> +
> +        ret = klvanc_create_AFD(&pkt);
> +        if (ret != 0)
> +            return AVERROR(ENOMEM);
> +
> +        ret = klvanc_set_AFD_val(pkt, data[0]);
> +        if (ret != 0) {
> +            av_log(avctx, AV_LOG_ERROR, "Invalid AFD value specified: %d\n",
> +                   data[0]);
> +            klvanc_destroy_AFD(pkt);
> +            return AVERROR(EINVAL);
> +        }
> +
> +        /* FIXME: Should really rely on the coded_width but seems like that
> +           is not accessible to libavdevice outputs */
> +        if (av_cmp_q((AVRational) {st->codecpar->width, st->codecpar->height}, (AVRational) {4, 3}) == 1)
> +            pkt->aspectRatio = ASPECT_16x9;
> +        else
> +            pkt->aspectRatio = ASPECT_4x3;
> +
> +        ret = klvanc_convert_AFD_to_words(pkt, &afd, &len);
> +        if (ret != 0) {
> +            av_log(avctx, AV_LOG_ERROR, "Failed converting 708 packet to words\n");
> +            return AVERROR(ENOMEM);
> +        }
> +        klvanc_destroy_AFD(pkt);

this destroy needs to go before the if I think.

> +
> +        ret = klvanc_line_insert(ctx->vanc_ctx, &vanc_lines, afd, len, 12, 0);
> +        if (ret != 0) {
> +            av_log(avctx, AV_LOG_ERROR, "VANC line insertion failed\n");
> +            return AVERROR(ENOMEM);
> +        }

And you need to free afd here, no?

> +    }
> +
>     IDeckLinkVideoFrameAncillary *vanc;
>     int result = ctx->dlo->CreateAncillaryData(bmdFormat10BitYUV, &vanc);
>     if (result != S_OK) {
> @@ -455,7 +495,7 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt)
>         frame = new decklink_frame(ctx, avpacket, st->codecpar->codec_id, ctx->bmd_height, ctx->bmd_width);
> 
> #if CONFIG_LIBKLVANC
> -        ret = decklink_construct_vanc(avctx, ctx, pkt, frame);
> +        ret = decklink_construct_vanc(avctx, ctx, pkt, frame, st);
>         if (ret != 0) {
>             av_log(avctx, AV_LOG_ERROR, "Failed to construct VANC\n");
>         }

Regards,
Marton


More information about the ffmpeg-devel mailing list