[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