diff mbox

[FFmpeg-devel] libavdevice/decklink: 32 bit audio support

Message ID 5823C84E-19DF-4E05-ABC0-72396DDD0BDA@dericed.com
State Superseded
Headers show

Commit Message

Dave Rice Oct. 16, 2017, 6:38 p.m. UTC
Hi,

I tested this with my Ultrastudio Express and confirmed that I'm getting higher bit depth recordings with the abitscope filter. This patch adds an option to get 32 bit audio as an input with the decklink device (beforehand only 16 bit audio was supported). This resolves http://trac.ffmpeg.org/ticket/6708 and is partly based upon Georg Lippitisch's earlier draft at https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.


From fbf2bd40471c8fa35374bb1a51c51a3f4f36b992 Mon Sep 17 00:00:00 2001
From: Dave Rice <dave@dericed.com>
Date: Thu, 12 Oct 2017 13:40:59 -0400
Subject: [PATCH] libavdevice/decklink: 32 bit audio support

Partially based upon Georg Lippitsch's patch at https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
---
 libavdevice/decklink_common.h   |  1 +
 libavdevice/decklink_common_c.h |  1 +
 libavdevice/decklink_dec.cpp    | 17 ++++++++++++++---
 libavdevice/decklink_dec_c.c    |  1 +
 4 files changed, 17 insertions(+), 3 deletions(-)

Comments

Paul B Mahol Oct. 16, 2017, 7:56 p.m. UTC | #1
On 10/16/17, Dave Rice <dave@dericed.com> wrote:
> Hi,
>
> I tested this with my Ultrastudio Express and confirmed that I'm getting
> higher bit depth recordings with the abitscope filter. This patch adds an
> option to get 32 bit audio as an input with the decklink device (beforehand
> only 16 bit audio was supported). This resolves
> http://trac.ffmpeg.org/ticket/6708 and is partly based upon Georg
> Lippitisch's earlier draft at
> https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
>
>
> From fbf2bd40471c8fa35374bb1a51c51a3f4f36b992 Mon Sep 17 00:00:00 2001
> From: Dave Rice <dave@dericed.com>
> Date: Thu, 12 Oct 2017 13:40:59 -0400
> Subject: [PATCH] libavdevice/decklink: 32 bit audio support
>
> Partially based upon Georg Lippitsch's patch at
> https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
> ---
>  libavdevice/decklink_common.h   |  1 +
>  libavdevice/decklink_common_c.h |  1 +
>  libavdevice/decklink_dec.cpp    | 17 ++++++++++++++---
>  libavdevice/decklink_dec_c.c    |  1 +
>  4 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
> index 6b2525fb53..b6acb01bb9 100644
> --- a/libavdevice/decklink_common.h
> +++ b/libavdevice/decklink_common.h
> @@ -97,6 +97,7 @@ struct decklink_ctx {
>      int frames_buffer_available_spots;
>
>      int channels;
> +    int audio_depth;
>  };
>
>  typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
> diff --git a/libavdevice/decklink_common_c.h
> b/libavdevice/decklink_common_c.h
> index 5616ab32f9..368ac259e4 100644
> --- a/libavdevice/decklink_common_c.h
> +++ b/libavdevice/decklink_common_c.h
> @@ -42,6 +42,7 @@ struct decklink_cctx {
>      double preroll;
>      int v210;
>      int audio_channels;
> +    int audio_depth;
>      int duplex_mode;
>      DecklinkPtsSource audio_pts_source;
>      DecklinkPtsSource video_pts_source;
> diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
> index d9ac01ac91..7e97d5f064 100644
> --- a/libavdevice/decklink_dec.cpp
> +++ b/libavdevice/decklink_dec.cpp
> @@ -771,7 +771,7 @@ HRESULT
> decklink_input_callback::VideoInputFrameArrived(
>          av_init_packet(&pkt);
>
>          //hack among hacks
> -        pkt.size = audioFrame->GetSampleFrameCount() *
> ctx->audio_st->codecpar->channels * (16 / 8);
> +        pkt.size = audioFrame->GetSampleFrameCount() *
> ctx->audio_st->codecpar->channels * (ctx->audio_depth / 8);
>          audioFrame->GetBytes(&audioFrameBytes);
>          audioFrame->GetPacketTime(&audio_pts,
> ctx->audio_st->time_base.den);
>          pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock,
> ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts);
> @@ -854,6 +854,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
> *avctx)
>      ctx->audio_pts_source = cctx->audio_pts_source;
>      ctx->video_pts_source = cctx->video_pts_source;
>      ctx->draw_bars = cctx->draw_bars;
> +    ctx->audio_depth = cctx->audio_depth;
>      cctx->ctx = ctx;
>
>      /* Check audio channel option for valid values: 2, 8 or 16 */
> @@ -866,6 +867,16 @@ av_cold int ff_decklink_read_header(AVFormatContext
> *avctx)
>              av_log(avctx, AV_LOG_ERROR, "Value of channels option must be
> one of 2, 8 or 16\n");
>              return AVERROR(EINVAL);
>      }
> +
> +    /* Check audio bit depth option for valid values: 16 or 32 */
> +    switch (cctx->audio_depth) {
> +        case 16:
> +        case 32:
> +            break;
> +        default:
> +            av_log(avctx, AV_LOG_ERROR, "Value for audio bit depth option
> must be either 16 or 32\n");
> +            return AVERROR(EINVAL);

This message is redundant with AVOptions, User should be able to
select only 16 or 32,
see bellow.

> +    }
>
>      /* List available devices. */
>      if (ctx->list_devices) {
> @@ -930,7 +941,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
> *avctx)
>          goto error;
>      }
>      st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
> -    st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16LE;
> +    st->codecpar->codec_id    = cctx->audio_depth == 32 ?
> AV_CODEC_ID_PCM_S32LE : AV_CODEC_ID_PCM_S16LE;
>      st->codecpar->sample_rate = bmdAudioSampleRate48kHz;
>      st->codecpar->channels    = cctx->audio_channels;
>      avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
> @@ -1021,7 +1032,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
> *avctx)
>      }
>
>      av_log(avctx, AV_LOG_VERBOSE, "Using %d input audio channels\n",
> ctx->audio_st->codecpar->channels);
> -    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz,
> bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
> +    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz,
> cctx->audio_depth == 32 ? bmdAudioSampleType32bitInteger :
> bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
>
>      if (result != S_OK) {
>          av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
> diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
> index 1127d23ada..1c6d826945 100644
> --- a/libavdevice/decklink_dec_c.c
> +++ b/libavdevice/decklink_dec_c.c
> @@ -72,6 +72,7 @@ static const AVOption options[] = {
>      { "wallclock",     NULL,                                          0,
> AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"},
>      { "draw_bars",     "draw bars on signal loss" , OFFSET(draw_bars),
> AV_OPT_TYPE_BOOL,  { .i64 = 1}, 0, 1, DEC },
>      { "queue_size",    "input queue buffer size",   OFFSET(queue_size),
> AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
> +    { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),
> AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },

Use AV_OPT_ ENUM instead.
Dave Rice Oct. 17, 2017, 1:22 p.m. UTC | #2
Hi Paul,

> On Oct 16, 2017, at 3:56 PM, Paul B Mahol <onemda@gmail.com> wrote:
> 
> On 10/16/17, Dave Rice <dave@dericed.com <mailto:dave@dericed.com>> wrote:
>> Hi,
>> 
>> I tested this with my Ultrastudio Express and confirmed that I'm getting
>> higher bit depth recordings with the abitscope filter. This patch adds an
>> option to get 32 bit audio as an input with the decklink device (beforehand
>> only 16 bit audio was supported). This resolves
>> http://trac.ffmpeg.org/ticket/6708 and is partly based upon Georg
>> Lippitisch's earlier draft at
>> https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
>> 
>> 
>> From fbf2bd40471c8fa35374bb1a51c51a3f4f36b992 Mon Sep 17 00:00:00 2001
>> From: Dave Rice <dave@dericed.com>
>> Date: Thu, 12 Oct 2017 13:40:59 -0400
>> Subject: [PATCH] libavdevice/decklink: 32 bit audio support
>> 
>> Partially based upon Georg Lippitsch's patch at
>> https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
>> ---
>> libavdevice/decklink_common.h   |  1 +
>> libavdevice/decklink_common_c.h |  1 +
>> libavdevice/decklink_dec.cpp    | 17 ++++++++++++++---
>> libavdevice/decklink_dec_c.c    |  1 +
>> 4 files changed, 17 insertions(+), 3 deletions(-)
>> 
>> diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
>> index 6b2525fb53..b6acb01bb9 100644
>> --- a/libavdevice/decklink_common.h
>> +++ b/libavdevice/decklink_common.h
>> @@ -97,6 +97,7 @@ struct decklink_ctx {
>>     int frames_buffer_available_spots;
>> 
>>     int channels;
>> +    int audio_depth;
>> };
>> 
>> typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
>> diff --git a/libavdevice/decklink_common_c.h
>> b/libavdevice/decklink_common_c.h
>> index 5616ab32f9..368ac259e4 100644
>> --- a/libavdevice/decklink_common_c.h
>> +++ b/libavdevice/decklink_common_c.h
>> @@ -42,6 +42,7 @@ struct decklink_cctx {
>>     double preroll;
>>     int v210;
>>     int audio_channels;
>> +    int audio_depth;
>>     int duplex_mode;
>>     DecklinkPtsSource audio_pts_source;
>>     DecklinkPtsSource video_pts_source;
>> diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
>> index d9ac01ac91..7e97d5f064 100644
>> --- a/libavdevice/decklink_dec.cpp
>> +++ b/libavdevice/decklink_dec.cpp
>> @@ -771,7 +771,7 @@ HRESULT
>> decklink_input_callback::VideoInputFrameArrived(
>>         av_init_packet(&pkt);
>> 
>>         //hack among hacks
>> -        pkt.size = audioFrame->GetSampleFrameCount() *
>> ctx->audio_st->codecpar->channels * (16 / 8);
>> +        pkt.size = audioFrame->GetSampleFrameCount() *
>> ctx->audio_st->codecpar->channels * (ctx->audio_depth / 8);
>>         audioFrame->GetBytes(&audioFrameBytes);
>>         audioFrame->GetPacketTime(&audio_pts,
>> ctx->audio_st->time_base.den);
>>         pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock,
>> ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts);
>> @@ -854,6 +854,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
>> *avctx)
>>     ctx->audio_pts_source = cctx->audio_pts_source;
>>     ctx->video_pts_source = cctx->video_pts_source;
>>     ctx->draw_bars = cctx->draw_bars;
>> +    ctx->audio_depth = cctx->audio_depth;
>>     cctx->ctx = ctx;
>> 
>>     /* Check audio channel option for valid values: 2, 8 or 16 */
>> @@ -866,6 +867,16 @@ av_cold int ff_decklink_read_header(AVFormatContext
>> *avctx)
>>             av_log(avctx, AV_LOG_ERROR, "Value of channels option must be
>> one of 2, 8 or 16\n");
>>             return AVERROR(EINVAL);
>>     }
>> +
>> +    /* Check audio bit depth option for valid values: 16 or 32 */
>> +    switch (cctx->audio_depth) {
>> +        case 16:
>> +        case 32:
>> +            break;
>> +        default:
>> +            av_log(avctx, AV_LOG_ERROR, "Value for audio bit depth option
>> must be either 16 or 32\n");
>> +            return AVERROR(EINVAL);
> 
> This message is redundant with AVOptions, User should be able to
> select only 16 or 32,
> see bellow.
> 
>> +    }
>> 
>>     /* List available devices. */
>>     if (ctx->list_devices) {
>> @@ -930,7 +941,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
>> *avctx)
>>         goto error;
>>     }
>>     st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
>> -    st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16LE;
>> +    st->codecpar->codec_id    = cctx->audio_depth == 32 ?
>> AV_CODEC_ID_PCM_S32LE : AV_CODEC_ID_PCM_S16LE;
>>     st->codecpar->sample_rate = bmdAudioSampleRate48kHz;
>>     st->codecpar->channels    = cctx->audio_channels;
>>     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
>> @@ -1021,7 +1032,7 @@ av_cold int ff_decklink_read_header(AVFormatContext
>> *avctx)
>>     }
>> 
>>     av_log(avctx, AV_LOG_VERBOSE, "Using %d input audio channels\n",
>> ctx->audio_st->codecpar->channels);
>> -    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz,
>> bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
>> +    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz,
>> cctx->audio_depth == 32 ? bmdAudioSampleType32bitInteger :
>> bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
>> 
>>     if (result != S_OK) {
>>         av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
>> diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
>> index 1127d23ada..1c6d826945 100644
>> --- a/libavdevice/decklink_dec_c.c
>> +++ b/libavdevice/decklink_dec_c.c
>> @@ -72,6 +72,7 @@ static const AVOption options[] = {
>>     { "wallclock",     NULL,                                          0,
>> AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"},
>>     { "draw_bars",     "draw bars on signal loss" , OFFSET(draw_bars),
>> AV_OPT_TYPE_BOOL,  { .i64 = 1}, 0, 1, DEC },
>>     { "queue_size",    "input queue buffer size",   OFFSET(queue_size),
>> AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
>> +    { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),
>> AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
> 
> Use AV_OPT_ ENUM instead.

I don't see there to be an AV_OPT_TYPE_ENUM. Could you point out how this works from an example? Alternatively since the decklink sdk only supports 2 bit depths (16 and 32), I could use a boolean here if that makes more sense.
Dave Rice
Moritz Barsnick Oct. 17, 2017, 2:40 p.m. UTC | #3
On Tue, Oct 17, 2017 at 09:22:27 -0400, Dave Rice wrote:
> >> --- a/libavdevice/decklink_dec_c.c
> >> +++ b/libavdevice/decklink_dec_c.c
> >> @@ -72,6 +72,7 @@ static const AVOption options[] = {
> >>     { "wallclock",     NULL,                                          0,
> >> AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"},
> >>     { "draw_bars",     "draw bars on signal loss" , OFFSET(draw_bars),
> >> AV_OPT_TYPE_BOOL,  { .i64 = 1}, 0, 1, DEC },
> >>     { "queue_size",    "input queue buffer size",   OFFSET(queue_size),
> >> AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
> >> +    { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),
> >> AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
> > 
> > Use AV_OPT_ ENUM instead.
> 
> I don't see there to be an AV_OPT_TYPE_ENUM. Could you point out how this works from an example? Alternatively since the decklink sdk only supports 2 bit depths (16 and 32), I could use a boolean here if that makes more sense.

I would guess Paul means:

enum audio_bitdepths {
    AUDIO_BITDEPTH_16,
    AUDIO_BITDEPTH_32,
    AUDIO_BITDEPTH_NB
};

    { "audio_depth",    "audio bitdepth", OFFSET(audio_depth), AV_OPT_TYPE_INT,   { .i64 = AUDIO_BITDEPTH_16 }, 0, AUDIO_BITDEPTH_NB-1, DEC, "audio_depth" },
        { "16",         "16 bits",                          0, AV_OPT_TYPE_CONST, { .i64 = AUDIO_BITDEPTH_16 }, 0, 0,                   DEC, "audio_depth" },
        { "32",         "32 bits",                          0, AV_OPT_TYPE_CONST, { .i64 = AUDIO_BITDEPTH_32 }, 0, 0,                   DEC, "audio_depth" },

I'm not sure pure digits are accepted as an option strin ("16", "32"), but, why shouldn't they.

It may seem like a bit of overkill for two values, but take into
consideration that you can skip the check "Check audio bit depth option
for valid values: 16 or 32", but need to map the enums to values
instead. Or you pre-assign the enums values (AUDIO_BITDEPTH_16 = 16,
...), but use some other trick to define the lowest possible value.[*]
And you can easily add 8 bit or 24 bit support. ;-)

Cheers,
Moritz

[*]
enum audio_bitdepths {
    AUDIO_BITDEPTH_LOWEST = 16,
    AUDIO_BITDEPTH_16     = 16,
    AUDIO_BITDEPTH_32     = 32,
    AUDIO_BITDEPTH_NB
};

    { "audio_depth",    "audio bitdepth", OFFSET(audio_depth), AV_OPT_TYPE_INT,   { .i64 = AUDIO_BITDEPTH_16 }, AUDIO_BITDEPTH_LOWEST, AUDIO_BITDEPTH_NB-1, DEC, "audio_depth" },
        { "16",         "16 bits",                          0, AV_OPT_TYPE_CONST, { .i64 = AUDIO_BITDEPTH_16 }, 0, 0, DEC, "audio_depth" },
        { "32",         "32 bits",                          0, AV_OPT_TYPE_CONST, { .i64 = AUDIO_BITDEPTH_32 }, 0, 0, DEC, "audio_depth" },
ffmpeg@dx9s.net Oct. 17, 2017, 7:24 p.m. UTC | #4
On 2017-10-17 06:22, Dave Rice wrote:

> I don't see there to be an AV_OPT_TYPE_ENUM. Could you point out how
> this works from an example? Alternatively since the decklink sdk only
> supports 2 bit depths (16 and 32), I could use a boolean here if that
> makes more sense.
> Dave Rice
> 

I am unsure about the AV_OPT_TYPE_ENUM as well so can't answer that. I 
would not use a boolean, even tho the audio word/sample sizes will 
probably never change from those two offerings. As stated in previous 
recent message/thread, from what I know about my card, it only has a 
24-bit ADC/DAC for audio and the 16-bit modes are either truncated or 
dithered in hardware or drivers. They might come out with higher end 
hardware that captures 32-bits PCM at some later date, they will have an 
additional defined constant which would require converting the boolean 
back into an int what your patch currently has (int I believe it was).

I will try the patch out when I can as it is something I want for two 
reasons (higher quality and see if it solves an audio glitch that 
occasionally pops up during capture, difficult to reproduce -- happens 
with their reference capture software under Linux as well so think it is 
hardware issue with HDMI splitter I have).

--Doug (dx9s)
Marton Balint Oct. 18, 2017, 7:07 p.m. UTC | #5
On Mon, 16 Oct 2017, Dave Rice wrote:

> Hi,
>
> I tested this with my Ultrastudio Express and confirmed that I'm getting 
> higher bit depth recordings with the abitscope filter. This patch adds 
> an option to get 32 bit audio as an input with the decklink device 
> (beforehand only 16 bit audio was supported). This resolves 
> http://trac.ffmpeg.org/ticket/6708 and is partly based upon Georg 
> Lippitisch's earlier draft at 
> https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
>
>
> From fbf2bd40471c8fa35374bb1a51c51a3f4f36b992 Mon Sep 17 00:00:00 2001
> From: Dave Rice <dave@dericed.com>
> Date: Thu, 12 Oct 2017 13:40:59 -0400
> Subject: [PATCH] libavdevice/decklink: 32 bit audio support
>
> Partially based upon Georg Lippitsch's patch at https://ffmpeg.org/pipermail/ffmpeg-devel/2015-January/167649.html.
> ---
> libavdevice/decklink_common.h   |  1 +
> libavdevice/decklink_common_c.h |  1 +
> libavdevice/decklink_dec.cpp    | 17 ++++++++++++++---
> libavdevice/decklink_dec_c.c    |  1 +
> 4 files changed, 17 insertions(+), 3 deletions(-)

Missing docs/indevs.texi update and libavdevice micro bump.

Regards,
Marton
diff mbox

Patch

diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 6b2525fb53..b6acb01bb9 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -97,6 +97,7 @@  struct decklink_ctx {
     int frames_buffer_available_spots;
 
     int channels;
+    int audio_depth;
 };
 
 typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index 5616ab32f9..368ac259e4 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -42,6 +42,7 @@  struct decklink_cctx {
     double preroll;
     int v210;
     int audio_channels;
+    int audio_depth;
     int duplex_mode;
     DecklinkPtsSource audio_pts_source;
     DecklinkPtsSource video_pts_source;
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index d9ac01ac91..7e97d5f064 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -771,7 +771,7 @@  HRESULT decklink_input_callback::VideoInputFrameArrived(
         av_init_packet(&pkt);
 
         //hack among hacks
-        pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (16 / 8);
+        pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (ctx->audio_depth / 8);
         audioFrame->GetBytes(&audioFrameBytes);
         audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);
         pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts);
@@ -854,6 +854,7 @@  av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     ctx->audio_pts_source = cctx->audio_pts_source;
     ctx->video_pts_source = cctx->video_pts_source;
     ctx->draw_bars = cctx->draw_bars;
+    ctx->audio_depth = cctx->audio_depth;
     cctx->ctx = ctx;
 
     /* Check audio channel option for valid values: 2, 8 or 16 */
@@ -866,6 +867,16 @@  av_cold int ff_decklink_read_header(AVFormatContext *avctx)
             av_log(avctx, AV_LOG_ERROR, "Value of channels option must be one of 2, 8 or 16\n");
             return AVERROR(EINVAL);
     }
+    
+    /* Check audio bit depth option for valid values: 16 or 32 */
+    switch (cctx->audio_depth) {
+        case 16:
+        case 32:
+            break;
+        default:
+            av_log(avctx, AV_LOG_ERROR, "Value for audio bit depth option must be either 16 or 32\n");
+            return AVERROR(EINVAL);
+    }
 
     /* List available devices. */
     if (ctx->list_devices) {
@@ -930,7 +941,7 @@  av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         goto error;
     }
     st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
-    st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16LE;
+    st->codecpar->codec_id    = cctx->audio_depth == 32 ? AV_CODEC_ID_PCM_S32LE : AV_CODEC_ID_PCM_S16LE;
     st->codecpar->sample_rate = bmdAudioSampleRate48kHz;
     st->codecpar->channels    = cctx->audio_channels;
     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
@@ -1021,7 +1032,7 @@  av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     }
 
     av_log(avctx, AV_LOG_VERBOSE, "Using %d input audio channels\n", ctx->audio_st->codecpar->channels);
-    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
+    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, cctx->audio_depth == 32 ? bmdAudioSampleType32bitInteger : bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
 
     if (result != S_OK) {
         av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index 1127d23ada..1c6d826945 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -72,6 +72,7 @@  static const AVOption options[] = {
     { "wallclock",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"},
     { "draw_bars",     "draw bars on signal loss" , OFFSET(draw_bars),    AV_OPT_TYPE_BOOL,  { .i64 = 1}, 0, 1, DEC },
     { "queue_size",    "input queue buffer size",   OFFSET(queue_size),   AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
+    { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),  AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
     { NULL },
 };