[FFmpeg-devel] [PATCHv2 2/4] avdevice/decklink_enc: add support to specify field order

Marton Balint cus at passwd.hu
Sat Feb 25 21:22:09 EET 2017


Changes: handle AV_FIELD_TB and AV_FIELD_BT as well.

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 doc/outdevs.texi                |  4 ++--
 libavdevice/decklink_common.cpp | 29 +++++++++++++++++++++++------
 libavdevice/decklink_common.h   |  2 +-
 libavdevice/decklink_enc.cpp    |  4 ++--
 libavdevice/version.h           |  2 +-
 5 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index e68653f..df41cc8 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -131,8 +131,8 @@ and @code{--extra-ldflags}.
 On Windows, you need to run the IDL files through @command{widl}.
 
 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
- at command{-list_formats 1}. Audio sample rate is always 48 kHz.
+uyvy422, framerate, field order and video size must be determined for your
+device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
 
 @subsection Options
 
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
index a3bc58d..8b499c5 100644
--- a/libavdevice/decklink_common.cpp
+++ b/libavdevice/decklink_common.cpp
@@ -130,9 +130,23 @@ static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfiguratio
     return 0;
 }
 
+static DECKLINK_BOOL field_order_eq(enum AVFieldOrder field_order, BMDFieldDominance bmd_field_order)
+{
+    if (field_order == AV_FIELD_UNKNOWN)
+        return true;
+    if ((field_order == AV_FIELD_TT || field_order == AV_FIELD_TB) && bmd_field_order == bmdUpperFieldFirst)
+        return true;
+    if ((field_order == AV_FIELD_BB || field_order == AV_FIELD_BT) && bmd_field_order == bmdLowerFieldFirst)
+        return true;
+    if (field_order == AV_FIELD_PROGRESSIVE && (bmd_field_order == bmdProgressiveFrame || bmd_field_order == bmdProgressiveSegmentedFrame))
+        return true;
+    return false;
+}
+
 int ff_decklink_set_format(AVFormatContext *avctx,
                                int width, int height,
                                int tb_num, int tb_den,
+                               enum AVFieldOrder field_order,
                                decklink_direction_t direction, int num)
 {
     struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
@@ -143,8 +157,8 @@ int ff_decklink_set_format(AVFormatContext *avctx,
     int i = 1;
     HRESULT res;
 
-    av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, direction %d, mode number %d\n",
-        width, height, tb_num, tb_den, direction, num);
+    av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d\n",
+        width, height, tb_num, tb_den, field_order, direction, num);
 
     if (ctx->duplex_mode) {
         DECKLINK_BOOL duplex_supported = false;
@@ -187,18 +201,21 @@ int ff_decklink_set_format(AVFormatContext *avctx,
         BMDTimeValue bmd_tb_num, bmd_tb_den;
         int bmd_width  = mode->GetWidth();
         int bmd_height = mode->GetHeight();
+        BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();
 
         mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
         AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den);
 
-        if ((bmd_width == width && bmd_height == height &&
-            !av_cmp_q(mode_tb, target_tb)) || i == num) {
+        if ((bmd_width == width &&
+             bmd_height == height &&
+             !av_cmp_q(mode_tb, target_tb) &&
+             field_order_eq(field_order, bmd_field_dominance)) || i == num) {
             ctx->bmd_mode   = mode->GetDisplayMode();
             ctx->bmd_width  = bmd_width;
             ctx->bmd_height = bmd_height;
             ctx->bmd_tb_den = bmd_tb_den;
             ctx->bmd_tb_num = bmd_tb_num;
-            ctx->bmd_field_dominance = mode->GetFieldDominance();
+            ctx->bmd_field_dominance = bmd_field_dominance;
             av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
                 bmd_width, bmd_height, 1/av_q2d(mode_tb),
                 (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
@@ -230,7 +247,7 @@ int ff_decklink_set_format(AVFormatContext *avctx,
 }
 
 int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num) {
-    return ff_decklink_set_format(avctx, 0, 0, 0, 0, direction, num);
+    return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction, num);
 }
 
 int ff_decklink_list_devices(AVFormatContext *avctx)
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index bfa2b08..4753287 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -128,7 +128,7 @@ static const BMDVideoConnection decklink_video_connection_map[] = {
 };
 
 HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);
-int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, decklink_direction_t direction = DIRECTION_OUT, int num = 0);
+int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT, int num = 0);
 int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num);
 int ff_decklink_list_devices(AVFormatContext *avctx);
 int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT);
diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp
index 944e9d3..8fb6a9c 100644
--- a/libavdevice/decklink_enc.cpp
+++ b/libavdevice/decklink_enc.cpp
@@ -105,8 +105,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st)
         return -1;
     }
     if (ff_decklink_set_format(avctx, c->width, c->height,
-                            st->time_base.num, st->time_base.den)) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported video size or framerate!"
+                            st->time_base.num, st->time_base.den, c->field_order)) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported video size, framerate or field order!"
                " Check available formats with -list_formats 1.\n");
         return -1;
     }
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 94f5659..ceec2d4 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVDEVICE_VERSION_MAJOR  57
 #define LIBAVDEVICE_VERSION_MINOR   2
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \
-- 
2.10.2



More information about the ffmpeg-devel mailing list