[FFmpeg-devel] [PATCH] 32 bit and 8/16 channel audio support for Decklink input

Georg Lippitsch georg.lippitsch at gmx.at
Sun Jan 18 20:44:34 CET 2015


Examples:

Capture video clip at 720p50 with 32bit audio:
ffmpeg -bm_audiodepth 32 -f decklink -i 'UltraStudio Mini Recorder at 14' -acodec copy -vcodec copy output.avi

Capture video clip at 576i50 with 8 audio channels:
ffmpeg -bm_channels 8 -f decklink -i 'UltraStudio Mini Recorder at 3' -acodec copy -vcodec copy output.avi
---
 libavdevice/decklink_common.h   |  1 +
 libavdevice/decklink_common_c.h |  2 ++
 libavdevice/decklink_dec.cpp    | 25 +++++++++++++++++++++----
 libavdevice/decklink_dec_c.c    |  2 ++
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 96912a7..e082767 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -77,6 +77,7 @@ struct decklink_ctx {
     sem_t semaphore;
 
     int channels;
+    int audiodepth;
 };
 
 typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index fb2b788..0cc183a 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -29,5 +29,7 @@ struct decklink_cctx {
     int list_formats;
     double preroll;
     int v210;
+    int channels;
+    int audiodepth;
 };
 
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 747f47e..cfb2ad9 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -292,7 +292,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
 
         c = ctx->audio_st->codec;
         //hack among hacks
-        pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codec->channels * (16 / 8);
+        pkt.size = audioFrame->GetSampleFrameCount() * ctx->channels *
+            (ctx->audiodepth / 8);
         audioFrame->GetBytes(&audioFrameBytes);
         audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);
         pkt.pts = audio_pts / ctx->audio_st->time_base.num;
@@ -379,6 +380,18 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     ctx->list_devices = cctx->list_devices;
     ctx->list_formats = cctx->list_formats;
     ctx->preroll      = cctx->preroll;
+    if (cctx->channels != 2 && cctx->channels != 8 && cctx->channels != 16) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels!"
+               " Only 2, 8 or 16 channels are supported.\n");
+        return AVERROR(EIO);
+    }
+    if (cctx->audiodepth != 16 && cctx->audiodepth != 32) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported audio bit depth!"
+               " Only 16 or 32 bit are supported.\n");
+        return AVERROR(EIO);
+    }
+    ctx->channels     = cctx->channels;
+    ctx->audiodepth   = cctx->audiodepth;
     cctx->ctx = ctx;
 
     iter = CreateDeckLinkIteratorInstance();
@@ -455,10 +468,11 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
         goto error;
     }
+
     st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
+    st->codec->codec_id    = cctx->audiodepth == 32 ? AV_CODEC_ID_PCM_S32LE : AV_CODEC_ID_PCM_S16LE;
     st->codec->sample_rate = bmdAudioSampleRate48kHz;
-    st->codec->channels    = 2;
+    st->codec->channels    = cctx->channels;
     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
     ctx->audio_st=st;
 
@@ -488,7 +502,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
 
     ctx->video_st=st;
 
-    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);
+    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz,
+                                        cctx->audiodepth == 32 ?
+                                        bmdAudioSampleType32bitInteger : bmdAudioSampleType16bitInteger,
+                                        cctx->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 b1a65e6..4d657ba 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -32,6 +32,8 @@ static const AVOption options[] = {
     { "list_devices", "list available devices"  , OFFSET(list_devices), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, DEC },
     { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, DEC },
     { "bm_v210",      "v210 10 bit per channel" , OFFSET(v210),         AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, DEC },
+    { "bm_channels",  "number of audio channels", OFFSET(channels),     AV_OPT_TYPE_INT   , { .i64 = 2   }, 2, 16, DEC },
+    { "bm_audiodepth","audio bit depth (16 or 32)", OFFSET(audiodepth), AV_OPT_TYPE_INT   , { .i64 = 16   }, 16, 32, DEC },
     { NULL },
 };
 
-- 
1.8.4.5



More information about the ffmpeg-devel mailing list