Commit 48f8ad32 authored by Marton Balint's avatar Marton Balint

avdevice/decklink_enc: add support to specify field order

Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent e0eb0bda
...@@ -131,8 +131,8 @@ and @code{--extra-ldflags}. ...@@ -131,8 +131,8 @@ 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{widl}.
DeckLink is very picky about the formats it supports. Pixel format is always 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 uyvy422, framerate, field order and video size must be determined for your
@command{-list_formats 1}. Audio sample rate is always 48 kHz. device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
@subsection Options @subsection Options
......
...@@ -130,9 +130,23 @@ static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfiguratio ...@@ -130,9 +130,23 @@ static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfiguratio
return 0; 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 ff_decklink_set_format(AVFormatContext *avctx,
int width, int height, int width, int height,
int tb_num, int tb_den, int tb_num, int tb_den,
enum AVFieldOrder field_order,
decklink_direction_t direction, int num) decklink_direction_t direction, int num)
{ {
struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
...@@ -143,8 +157,8 @@ int ff_decklink_set_format(AVFormatContext *avctx, ...@@ -143,8 +157,8 @@ int ff_decklink_set_format(AVFormatContext *avctx,
int i = 1; int i = 1;
HRESULT res; 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", 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, direction, num); width, height, tb_num, tb_den, field_order, direction, num);
if (ctx->duplex_mode) { if (ctx->duplex_mode) {
DECKLINK_BOOL duplex_supported = false; DECKLINK_BOOL duplex_supported = false;
...@@ -187,18 +201,21 @@ int ff_decklink_set_format(AVFormatContext *avctx, ...@@ -187,18 +201,21 @@ int ff_decklink_set_format(AVFormatContext *avctx,
BMDTimeValue bmd_tb_num, bmd_tb_den; BMDTimeValue bmd_tb_num, bmd_tb_den;
int bmd_width = mode->GetWidth(); int bmd_width = mode->GetWidth();
int bmd_height = mode->GetHeight(); int bmd_height = mode->GetHeight();
BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();
mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
AVRational mode_tb = av_make_q(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 && if ((bmd_width == width &&
!av_cmp_q(mode_tb, target_tb)) || i == num) { 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_mode = mode->GetDisplayMode();
ctx->bmd_width = bmd_width; ctx->bmd_width = bmd_width;
ctx->bmd_height = bmd_height; ctx->bmd_height = bmd_height;
ctx->bmd_tb_den = bmd_tb_den; ctx->bmd_tb_den = bmd_tb_den;
ctx->bmd_tb_num = bmd_tb_num; 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", 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), bmd_width, bmd_height, 1/av_q2d(mode_tb),
(ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":""); (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
...@@ -230,7 +247,7 @@ int ff_decklink_set_format(AVFormatContext *avctx, ...@@ -230,7 +247,7 @@ int ff_decklink_set_format(AVFormatContext *avctx,
} }
int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num) { 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) int ff_decklink_list_devices(AVFormatContext *avctx)
......
...@@ -128,7 +128,7 @@ static const BMDVideoConnection decklink_video_connection_map[] = { ...@@ -128,7 +128,7 @@ static const BMDVideoConnection decklink_video_connection_map[] = {
}; };
HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName); 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_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num);
int ff_decklink_list_devices(AVFormatContext *avctx); int ff_decklink_list_devices(AVFormatContext *avctx);
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT); int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT);
......
...@@ -105,8 +105,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) ...@@ -105,8 +105,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st)
return -1; return -1;
} }
if (ff_decklink_set_format(avctx, c->width, c->height, if (ff_decklink_set_format(avctx, c->width, c->height,
st->time_base.num, st->time_base.den)) { st->time_base.num, st->time_base.den, c->field_order)) {
av_log(avctx, AV_LOG_ERROR, "Unsupported video size or framerate!" av_log(avctx, AV_LOG_ERROR, "Unsupported video size, framerate or field order!"
" Check available formats with -list_formats 1.\n"); " Check available formats with -list_formats 1.\n");
return -1; return -1;
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MAJOR 57
#define LIBAVDEVICE_VERSION_MINOR 2 #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, \ #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \ LIBAVDEVICE_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment