[FFmpeg-devel] [PATCH 3/3] avdevice/decklink: Add support for decoding 8-bit RGB formats.

Chris Spencer spencercw at gmail.com
Sat Jul 18 21:20:26 CEST 2015


This adds a new pixel_format option to allow argb or bgra inputs. This is necessary to capture RGB HDMI inputs.

Signed-off-by: Chris Spencer <spencercw at gmail.com>
---
 doc/indevs.texi                 | 25 +++++++++++++++--------
 doc/outdevs.texi                |  2 +-
 libavdevice/decklink_common.cpp |  4 ++--
 libavdevice/decklink_common.h   |  1 +
 libavdevice/decklink_common_c.h |  1 +
 libavdevice/decklink_dec.cpp    | 44 +++++++++++++++++++++++++++++++++++------
 libavdevice/decklink_dec_c.c    |  7 ++++---
 libavdevice/decklink_enc.cpp    |  2 ++
 8 files changed, 66 insertions(+), 20 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index d5415bb..fd5fe57 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -158,12 +158,12 @@ DeckLink devices.
 To enable this input device, you need the Blackmagic DeckLink SDK and you
 need to configure with the appropriate @code{--extra-cflags}
 and @code{--extra-ldflags}.
-On Windows, you need to run the IDL files through @command{widl}.
+On Windows, you need to run the IDL files through @command{midl}.
 
-DeckLink is very picky about the formats it supports. Pixel format is
-uyvy422 or v210, framerate and video size must be determined for your device with
- at command{-list_formats 1}. Audio sample rate is always 48 kHz and the number
-of channels can be 2, 8 or 16.
+DeckLink is very picky about the formats it supports. Pixel format is uyvy422,
+v210, argb or bgra, framerate and video size must be determined for your device
+with @command{-list_formats 1}. Audio sample rate is always 48 kHz and the
+number of channels can be 2, 8 or 16.
 
 @subsection Options
 
@@ -177,9 +177,18 @@ Defaults to @option{false}.
 If set to @option{true}, print a list of supported formats and exit.
 Defaults to @option{false}.
 
- at item bm_v210
-If set to @samp{1}, video is captured in 10 bit v210 instead
-of uyvy422. Not all Blackmagic devices support this option.
+ at item bm_v210 @emph{(deprecated)}
+If set to @samp{1}, video is captured in 10 bit v210 instead of uyvy422. Not all
+Blackmagic devices support this option. This option is deprecated, use
+ at option{pixel_format=yuv422p10} instead.
+
+ at item pixel_format
+Sets the pixel format for the device to use. If the pixel format does not match
+the input source you may not get any video (it may be necessary to use an RGB
+format if capturing HDMI from a computer graphics card, for instance). Not all
+Blackmagic devices support all formats. Available pixel formats are:
+ at code{uyvy422, yuv422p10, argb, bgra}
+Defaults to @option{uyvy422}.
 
 @end table
 
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index e68653f..6015d29 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -128,7 +128,7 @@ DeckLink devices.
 To enable this output device, you need the Blackmagic DeckLink SDK and you
 need to configure with the appropriate @code{--extra-cflags}
 and @code{--extra-ldflags}.
-On Windows, you need to run the IDL files through @command{widl}.
+On Windows, you need to run the IDL files through @command{midl}.
 
 DeckLink is very picky about the formats it supports. Pixel format is always
 uyvy422, framerate and video size must be determined for your device with
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
index ac7964c..49a1487 100644
--- a/libavdevice/decklink_common.cpp
+++ b/libavdevice/decklink_common.cpp
@@ -157,12 +157,12 @@ int ff_decklink_set_format(AVFormatContext *avctx,
     if (ctx->bmd_mode == bmdModeUnknown)
         return -1;
     if (direction == DIRECTION_IN) {
-        if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
+        if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, ctx->bmd_format,
                                            bmdVideoOutputFlagDefault,
                                            &support, NULL) != S_OK)
             return -1;
     } else {
-        if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
+        if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, ctx->bmd_format,
                                            bmdVideoOutputFlagDefault,
                                            &support, NULL) != S_OK)
         return -1;
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 41fb5fb..5f3cab9 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -46,6 +46,7 @@ struct decklink_ctx {
     BMDTimeValue bmd_tb_den;
     BMDTimeValue bmd_tb_num;
     BMDDisplayMode bmd_mode;
+    BMDPixelFormat bmd_format;
     int bmd_width;
     int bmd_height;
     int bmd_field_dominance;
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index fb2b788..28db96c 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -29,5 +29,6 @@ struct decklink_cctx {
     int list_formats;
     double preroll;
     int v210;
+    enum AVPixelFormat pixel_format;
 };
 
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 747f47e..5ad1f0c 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -27,6 +27,7 @@
 extern "C" {
 #include "libavformat/avformat.h"
 #include "libavformat/internal.h"
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 }
 
@@ -426,6 +427,28 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         return AVERROR(EIO);
     }
 
+    /* Set pixel format. */
+    if (cctx->v210) {
+        av_log(avctx, AV_LOG_WARNING, "The bm_v210 option is deprecated and is "
+               "overriding the pixel_format option, use pixel_format=yuv422p10 "
+               "instead\n");
+        ctx->bmd_format = bmdFormat10BitYUV;
+    } else if (cctx->pixel_format == AV_PIX_FMT_UYVY422) {
+        ctx->bmd_format = bmdFormat8BitYUV;
+    } else if (cctx->pixel_format == AV_PIX_FMT_YUV422P10) {
+        ctx->bmd_format = bmdFormat10BitYUV;
+    } else if (cctx->pixel_format == AV_PIX_FMT_ARGB) {
+        ctx->bmd_format = bmdFormat8BitARGB;
+    } else if (cctx->pixel_format == AV_PIX_FMT_BGRA) {
+        ctx->bmd_format = bmdFormat8BitBGRA;
+    } else {
+        av_log(avctx, AV_LOG_WARNING, "Unsupported pixel format %d\n",
+               cctx->pixel_format);
+        ctx->dli->Release();
+        ctx->dl->Release();
+        return AVERROR_EXIT;
+    }
+
     /* List supported formats. */
     if (ctx->list_formats) {
         ff_decklink_list_formats(avctx, DIRECTION_IN);
@@ -475,13 +498,23 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     st->codec->time_base.num      = ctx->bmd_tb_num;
     st->codec->bit_rate    = avpicture_get_size(st->codec->pix_fmt, ctx->bmd_width, ctx->bmd_height) * 1/av_q2d(st->codec->time_base) * 8;
 
-    if (cctx->v210) {
-        st->codec->codec_id    = AV_CODEC_ID_V210;
-        st->codec->codec_tag   = MKTAG('V', '2', '1', '0');
-    } else {
+    if (ctx->bmd_format == bmdFormat8BitYUV) {
         st->codec->codec_id    = AV_CODEC_ID_RAWVIDEO;
         st->codec->pix_fmt     = AV_PIX_FMT_UYVY422;
         st->codec->codec_tag   = MKTAG('U', 'Y', 'V', 'Y');
+    } else if (ctx->bmd_format == bmdFormat10BitYUV) {
+        st->codec->codec_id    = AV_CODEC_ID_V210;
+        st->codec->codec_tag   = MKTAG('V', '2', '1', '0');
+    } else if (ctx->bmd_format == bmdFormat8BitARGB) {
+        st->codec->codec_id    = AV_CODEC_ID_RAWVIDEO;
+        st->codec->pix_fmt     = AV_PIX_FMT_ARGB;
+        st->codec->codec_tag   = MKTAG('A', 'R', 'G', 'B');
+    } else if (ctx->bmd_format == bmdFormat8BitBGRA) {
+        st->codec->codec_id    = AV_CODEC_ID_RAWVIDEO;
+        st->codec->pix_fmt     = AV_PIX_FMT_BGRA;
+        st->codec->codec_tag   = MKTAG('B', 'G', 'R', 'A');
+    } else {
+        av_assert0(0);
     }
 
     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
@@ -495,8 +528,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         goto error;
     }
 
-    result = ctx->dli->EnableVideoInput(ctx->bmd_mode,
-                                        cctx->v210 ? bmdFormat10BitYUV : bmdFormat8BitYUV,
+    result = ctx->dli->EnableVideoInput(ctx->bmd_mode, ctx->bmd_format,
                                         bmdVideoInputFlagDefault);
 
     if (result != S_OK) {
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index b1a65e6..d999b39 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -29,9 +29,10 @@
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 
 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 },
+    { "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 (deprecated)" , OFFSET(v210),         AV_OPT_TYPE_INT      , { .i64 = 0                  }, 0, 1,       DEC },
+    { "pixel_format", "set video pixel format"               , OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, { .i64 = AV_PIX_FMT_UYVY422 }, 0, INT_MAX, DEC },
     { NULL },
 };
 
diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp
index 6c5450f..dceecc8 100644
--- a/libavdevice/decklink_enc.cpp
+++ b/libavdevice/decklink_enc.cpp
@@ -104,6 +104,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st)
                " Only AV_PIX_FMT_UYVY422 is supported.\n");
         return -1;
     }
+    ctx->bmd_format = bmdFormat8BitYUV;
+
     if (ff_decklink_set_format(avctx, c->width, c->height,
                             c->time_base.num, c->time_base.den)) {
         av_log(avctx, AV_LOG_ERROR, "Unsupported video size or framerate!"
-- 
1.9.5.msysgit.1



More information about the ffmpeg-devel mailing list