bump On 5/16/16, 9:28 AM, "ffmpeg-devel on behalf of Felt, Patrick" <ffmpeg-devel-boun...@ffmpeg.org on behalf of patrick.f...@echostar.com> wrote:
>bump > >On 5/12/16, 4:07 PM, "ffmpeg-devel on behalf of Felt, Patrick" ><ffmpeg-devel-boun...@ffmpeg.org on behalf of patrick.f...@echostar.com> wrote: > >>I hang my head in shame. I neglected to notice that time wasn’t already >>included and so I had to modify the patch. Apologies for the noise. >> >>-- Add input mode autodetect to the decklink module. Previously users had to >>supply the input format like this 'DeckLink Device@modenum'. This patch >>allows users to either leave it off completely, or supply 0 or negative >>number to indicate autodetect is requested. Autodetect only works the first >>time so if the mode changes mid stream you'll die >> >>--- >> libavdevice/decklink_common.cpp | 110 >> ++++++++++++++++++++++++++++++++++++++++ >> libavdevice/decklink_common.h | 5 ++ >> libavdevice/decklink_common_c.h | 1 + >> libavdevice/decklink_dec.cpp | 86 +++++++++++++++++++++++++------ >> libavdevice/decklink_dec_c.c | 1 + >> 5 files changed, 188 insertions(+), 15 deletions(-) >> >>diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp >>index ac7964c..1d51294 100644 >>--- a/libavdevice/decklink_common.cpp >>+++ b/libavdevice/decklink_common.cpp >>@@ -98,6 +98,90 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, >>const char **displayName) >> return hr; >> } >> >>+long ff_decklink_mode_to_bm(AVFormatContext *avctx, >>+ decklink_direction_t direction, >>+ int ffmpeg_mode, >>+ IDeckLinkDisplayMode **mode) >>+{ >>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>+ IDeckLinkDisplayModeIterator *itermode; >>+ IDeckLinkDisplayMode *internal_mode; >>+ >>+ int result=0; >>+ HRESULT res; >>+ >>+ if (direction == DIRECTION_IN) { >>+ res = ctx->dli->GetDisplayModeIterator (&itermode); >>+ } else { >>+ res = ctx->dlo->GetDisplayModeIterator (&itermode); >>+ } >>+ >>+ if (res != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not get the mode iterator\n"); >>+ return -1; >>+ } >>+ >>+ while (itermode->Next(&internal_mode) == S_OK) { >>+ if (++result == ffmpeg_mode) { >>+ break; >>+ } >>+ >>+ internal_mode->Release(); >>+ } >>+ >>+ itermode->Release(); >>+ if (internal_mode) { >>+ result = internal_mode->GetDisplayMode(); >>+ if (mode) { >>+ *mode = internal_mode; >>+ } else { >>+ internal_mode->Release(); >>+ } >>+ >>+ return result; >>+ } >>+ >>+ return 0; >>+} >>+ >>+int ff_decklink_mode_to_ffmpeg(AVFormatContext *avctx, >>+ decklink_direction_t direction, >>+ IDeckLinkDisplayMode **mode) >>+{ >>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>+ IDeckLinkDisplayModeIterator *itermode; >>+ IDeckLinkDisplayMode *internal_mode; >>+ long bdm_mode_number = (*mode)->GetDisplayMode(); >>+ int result=1, found=0; >>+ HRESULT res; >>+ >>+ if (direction == DIRECTION_IN) { >>+ res = ctx->dli->GetDisplayModeIterator (&itermode); >>+ } else { >>+ res = ctx->dlo->GetDisplayModeIterator (&itermode); >>+ } >>+ >>+ if (res != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not get the mode iterator\n"); >>+ return -1; >>+ } >>+ >>+ while (itermode->Next(&internal_mode) == S_OK) { >>+ if (internal_mode->GetDisplayMode() == bdm_mode_number) { >>+ internal_mode->Release(); >>+ found = 1; >>+ break; >>+ } >>+ internal_mode->Release(); >>+ result++; >>+ } >>+ >>+ itermode->Release(); >>+ return (found) ? result : -1; >>+} >>+ >> int ff_decklink_set_format(AVFormatContext *avctx, >> int width, int height, >> int tb_num, int tb_den, >>@@ -197,6 +281,29 @@ int ff_decklink_list_devices(AVFormatContext *avctx) >> return 0; >> } >> >>+int ff_decklink_device_autodetect(AVFormatContext *avctx) >>+{ >>+ HRESULT res; >>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>+ IDeckLinkAttributes *attrs = NULL; >>+ bool auto_detect; >>+ >>+ res = ctx->dl->QueryInterface(IID_IDeckLinkAttributes, (void**)&attrs); >>+ if (res != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not get decklink attributes\n"); >>+ return -1; >>+ } >>+ >>+ res = attrs->GetFlag(BMDDeckLinkSupportsInputFormatDetection, >>&auto_detect); >>+ if (res != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Attribute fetch failed\n"); >>+ return -1; >>+ } >>+ >>+ return (auto_detect) ? 1 : 0; >>+} >>+ >> int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t >> direction) >> { >> struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>@@ -219,6 +326,9 @@ int ff_decklink_list_formats(AVFormatContext *avctx, >>decklink_direction_t direct >> >> av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", >> avctx->filename); >>+ if (ff_decklink_device_autodetect(avctx)) { >>+ av_log(avctx, AV_LOG_INFO, "\t-1\tAuto detection supported\n"); >>+ } >> while (itermode->Next(&mode) == S_OK) { >> BMDTimeValue tb_num, tb_den; >> mode->GetFrameRate(&tb_num, &tb_den); >>diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h >>index dff4fc1..cbe8de2 100644 >>--- a/libavdevice/decklink_common.h >>+++ b/libavdevice/decklink_common.h >>@@ -84,6 +84,8 @@ struct decklink_ctx { >> sem_t semaphore; >> >> int channels; >>+ int mode_num; >>+ int auto_detect; >> }; >> >> typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; >>@@ -105,5 +107,8 @@ int ff_decklink_set_format(AVFormatContext *avctx, int >>width, int height, int tb >> 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); >>+int ff_decklink_device_autodetect(AVFormatContext *avctx); >>+int ff_decklink_mode_to_ffmpeg(AVFormatContext *avctx, decklink_direction_t >>direction, IDeckLinkDisplayMode **mode); >>+long ff_decklink_mode_to_bm(AVFormatContext *avctx, decklink_direction_t >>direction, int ffmpeg_mode, IDeckLinkDisplayMode **mode); >> >> #endif /* AVDEVICE_DECKLINK_COMMON_H */ >>diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h >>index 2b5d92f..0d365be 100644 >>--- a/libavdevice/decklink_common_c.h >>+++ b/libavdevice/decklink_common_c.h >>@@ -34,6 +34,7 @@ struct decklink_cctx { >> double preroll; >> int v210; >> int audio_channels; >>+ int autodetect_delay; >> }; >> >> #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ >>diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >>index 1c305f3..7f33909 100644 >>--- a/libavdevice/decklink_dec.cpp >>+++ b/libavdevice/decklink_dec.cpp >>@@ -1,5 +1,5 @@ >> /* >>- * Blackmagic DeckLink output >>+ * Blackmagic DeckLink input >> * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl >> * >> * This file is part of FFmpeg. >>@@ -32,6 +32,7 @@ extern "C" { >> #if CONFIG_LIBZVBI >> #include <libzvbi.h> >> #endif >>+#include "libavutil/time.h" >> } >> >> #include "decklink_common.h" >>@@ -244,6 +245,12 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >> BMDTimeValue frameTime; >> BMDTimeValue frameDuration; >> >>+ /* if we don't have video, we are in the autodetect phase. skip >>everything and let >>+ * autodetect do its magic */ >>+ if (!ctx->video) { >>+ return S_OK; >>+ } >>+ >> ctx->frameCount++; >> >> // Handle Video Frame >>@@ -393,6 +400,14 @@ HRESULT decklink_input_callback::VideoInputFormatChanged( >> BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, >> BMDDetectedVideoInputFormatFlags) >> { >>+ >>+ /* undo all the autodetect stuff so we can move on with life */ >>+ ctx->dli->PauseStreams(); >>+ ctx->dli->FlushStreams(); >>+ >>+ ctx->mode_num = ff_decklink_mode_to_ffmpeg(avctx, DIRECTION_IN, &mode); >>+ ctx->video = 1; >>+ >> return S_OK; >> } >> >>@@ -435,14 +450,14 @@ av_cold int ff_decklink_read_header(AVFormatContext >>*avctx) >> { >> struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >> struct decklink_ctx *ctx; >>- IDeckLinkDisplayModeIterator *itermode; >> IDeckLinkIterator *iter; >> IDeckLink *dl = NULL; >> AVStream *st; >> HRESULT result; >> char fname[1024]; >> char *tmp; >>- int mode_num = 0; >>+ int auto_detect = 0; >>+ unsigned int autodetect_delay = cctx->autodetect_delay; >> >> ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx)); >> if (!ctx) >>@@ -486,7 +501,7 @@ av_cold int ff_decklink_read_header(AVFormatContext >>*avctx) >> strcpy (fname, avctx->filename); >> tmp=strchr (fname, '@'); >> if (tmp != NULL) { >>- mode_num = atoi (tmp+1); >>+ ctx->mode_num = atoi (tmp+1); >> *tmp = 0; >> } >> >>@@ -510,34 +525,74 @@ av_cold int ff_decklink_read_header(AVFormatContext >>*avctx) >> >> /* Get input device. */ >> if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != >> S_OK) { >>- av_log(avctx, AV_LOG_ERROR, "Could not open output device from >>'%s'\n", >>+ av_log(avctx, AV_LOG_ERROR, "Could not open input device from >>'%s'\n", >> avctx->filename); >> ctx->dl->Release(); >> return AVERROR(EIO); >> } >> >>+ auto_detect = ff_decklink_device_autodetect(avctx); >>+ >> /* List supported formats. */ >>- if (ctx->list_formats) { >>+ if (ctx->list_formats || (ctx->mode_num <= 0 && !auto_detect)) { >> ff_decklink_list_formats(avctx, DIRECTION_IN); >> ctx->dli->Release(); >> ctx->dl->Release(); >> return AVERROR_EXIT; >> } >> >>- if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) { >>- av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); >>- ctx->dl->Release(); >>- return AVERROR(EIO); >>- } >>+ if (ctx->mode_num <= 0 && auto_detect) { >>+ /* the user is wanting to auto detect the mode. we need to fake out >>the api and not start ffmpeg fully in this mode!*/ >>+ ctx->auto_detect = 1; >>+ ctx->mode_num = 1; /* it is assumed that there is at least one mode >>supported on a decklink card. */ >>+ >>+ if (ff_decklink_set_format(avctx, DIRECTION_IN, ctx->mode_num) < 0) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not set mode %d\n", >>ctx->mode_num); >>+ goto error; >>+ } >> >>- if (mode_num > 0) { >>- if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) { >>- av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", >>mode_num, fname); >>+ ctx->bmd_mode = ff_decklink_mode_to_bm(avctx, DIRECTION_IN, >>ctx->mode_num, NULL); >>+ result = ctx->dli->EnableVideoInput(ctx->bmd_mode, >>+ cctx->v210 ? bmdFormat10BitYUV : >>bmdFormat8BitYUV, >>+ bmdVideoInputFlagDefault | >>bmdVideoInputEnableFormatDetection); >>+ if (result != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not enable video in the >>pre-startup autodectect mode\n"); >> goto error; >> } >>+ >>+ result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, >>bmdAudioSampleType16bitInteger, cctx->audio_channels); >>+ if (result != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not enable audio in the >>pre-startup autodetect mode\n"); >>+ goto error; >>+ } >>+ >>+ result = decklink_start_input(avctx); >>+ if (result != S_OK) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not start input in the >>pre-startup autodetect mode\n"); >>+ goto error; >>+ } >>+ >>+ /* we need to give the auto detect code some time to figure out what >>mode we are really in */ >>+ autodetect_delay = cctx->autodetect_delay; >>+ while (!ctx->video) { >>+ if (autodetect_delay--) { >>+ /* this could indicate we are in the right mode. let's >>assume so */ >>+ break; >>+ } >>+ /* sleep for 1 second */ >>+ av_usleep(100000); >>+ } >> } >> >>- itermode->Release(); >>+ /* regardless as to if we did autodetect or not, we should now be in a >>position to >>+ * continue on as before with all the right setup to ensure we get the >>right mode */ >>+ ctx->video = 1; >>+ if (ctx->mode_num > 0) { >>+ if (ff_decklink_set_format(avctx, DIRECTION_IN, ctx->mode_num) < 0) { >>+ av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", >>ctx->mode_num, fname); >>+ goto error; >>+ } >>+ } >> >> /* Setup streams. */ >> st = avformat_new_stream(avctx, NULL); >>@@ -618,6 +673,7 @@ av_cold int ff_decklink_read_header(AVFormatContext >>*avctx) >> >> return 0; >> >>+ >> error: >> >> ctx->dli->Release(); >>diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c >>index 40c21a7..3f83f8f 100644 >>--- a/libavdevice/decklink_dec_c.c >>+++ b/libavdevice/decklink_dec_c.c >>@@ -36,6 +36,7 @@ static const AVOption options[] = { >> { "standard", NULL, 0, >> AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, >> { "all", NULL, 0, >> AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, >> { "channels", "number of audio channels", OFFSET(audio_channels), >> AV_OPT_TYPE_INT , { .i64 = 2 }, 2, 16, DEC }, >>+ { "autodetect_delay", "number of seconds to wait for autodetect to >>complete", OFFSET(autodetect_delay), AV_OPT_TYPE_INT , { .i64 = 5 }, 1, 30, >>DEC }, >> { NULL }, >> }; >> >>-- >>2.7.4 >> >> >> >>On 5/12/16, 3:21 PM, "ffmpeg-devel on behalf of Felt, Patrick" >><ffmpeg-devel-boun...@ffmpeg.org on behalf of patrick.f...@echostar.com> >>wrote: >> >>>-- Add input mode autodetect to the decklink module. Previously users had to >>>supply the input format like this 'DeckLink Device@modenum'. This patch >>>allows users to either leave it off completely, or supply 0 or negative >>>number to indicate autodetect is requested. Autodetect only works the first >>>time so if the mode changes mid stream you'll die >>> >>> >>>--- >>> libavdevice/decklink_common.cpp | 110 >>> ++++++++++++++++++++++++++++++++++++++++ >>> libavdevice/decklink_common.h | 5 ++ >>> libavdevice/decklink_common_c.h | 1 + >>> libavdevice/decklink_dec.cpp | 85 +++++++++++++++++++++++++------ >>> libavdevice/decklink_dec_c.c | 1 + >>> 5 files changed, 187 insertions(+), 15 deletions(-) >>> >>>diff --git a/libavdevice/decklink_common.cpp >>>b/libavdevice/decklink_common.cpp >>>index ac7964c..1d51294 100644 >>>--- a/libavdevice/decklink_common.cpp >>>+++ b/libavdevice/decklink_common.cpp >>>@@ -98,6 +98,90 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, >>>const char **displayName) >>> return hr; >>> } >>> >>>+long ff_decklink_mode_to_bm(AVFormatContext *avctx, >>>+ decklink_direction_t direction, >>>+ int ffmpeg_mode, >>>+ IDeckLinkDisplayMode **mode) >>>+{ >>>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>>+ IDeckLinkDisplayModeIterator *itermode; >>>+ IDeckLinkDisplayMode *internal_mode; >>>+ >>>+ int result=0; >>>+ HRESULT res; >>>+ >>>+ if (direction == DIRECTION_IN) { >>>+ res = ctx->dli->GetDisplayModeIterator (&itermode); >>>+ } else { >>>+ res = ctx->dlo->GetDisplayModeIterator (&itermode); >>>+ } >>>+ >>>+ if (res != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not get the mode iterator\n"); >>>+ return -1; >>>+ } >>>+ >>>+ while (itermode->Next(&internal_mode) == S_OK) { >>>+ if (++result == ffmpeg_mode) { >>>+ break; >>>+ } >>>+ >>>+ internal_mode->Release(); >>>+ } >>>+ >>>+ itermode->Release(); >>>+ if (internal_mode) { >>>+ result = internal_mode->GetDisplayMode(); >>>+ if (mode) { >>>+ *mode = internal_mode; >>>+ } else { >>>+ internal_mode->Release(); >>>+ } >>>+ >>>+ return result; >>>+ } >>>+ >>>+ return 0; >>>+} >>>+ >>>+int ff_decklink_mode_to_ffmpeg(AVFormatContext *avctx, >>>+ decklink_direction_t direction, >>>+ IDeckLinkDisplayMode **mode) >>>+{ >>>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>>+ IDeckLinkDisplayModeIterator *itermode; >>>+ IDeckLinkDisplayMode *internal_mode; >>>+ long bdm_mode_number = (*mode)->GetDisplayMode(); >>>+ int result=1, found=0; >>>+ HRESULT res; >>>+ >>>+ if (direction == DIRECTION_IN) { >>>+ res = ctx->dli->GetDisplayModeIterator (&itermode); >>>+ } else { >>>+ res = ctx->dlo->GetDisplayModeIterator (&itermode); >>>+ } >>>+ >>>+ if (res != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not get the mode iterator\n"); >>>+ return -1; >>>+ } >>>+ >>>+ while (itermode->Next(&internal_mode) == S_OK) { >>>+ if (internal_mode->GetDisplayMode() == bdm_mode_number) { >>>+ internal_mode->Release(); >>>+ found = 1; >>>+ break; >>>+ } >>>+ internal_mode->Release(); >>>+ result++; >>>+ } >>>+ >>>+ itermode->Release(); >>>+ return (found) ? result : -1; >>>+} >>>+ >>> int ff_decklink_set_format(AVFormatContext *avctx, >>> int width, int height, >>> int tb_num, int tb_den, >>>@@ -197,6 +281,29 @@ int ff_decklink_list_devices(AVFormatContext *avctx) >>> return 0; >>> } >>> >>>+int ff_decklink_device_autodetect(AVFormatContext *avctx) >>>+{ >>>+ HRESULT res; >>>+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>>+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; >>>+ IDeckLinkAttributes *attrs = NULL; >>>+ bool auto_detect; >>>+ >>>+ res = ctx->dl->QueryInterface(IID_IDeckLinkAttributes, (void**)&attrs); >>>+ if (res != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not get decklink attributes\n"); >>>+ return -1; >>>+ } >>>+ >>>+ res = attrs->GetFlag(BMDDeckLinkSupportsInputFormatDetection, >>>&auto_detect); >>>+ if (res != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Attribute fetch failed\n"); >>>+ return -1; >>>+ } >>>+ >>>+ return (auto_detect) ? 1 : 0; >>>+} >>>+ >>> int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t >>> direction) >>> { >>> struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>>@@ -219,6 +326,9 @@ int ff_decklink_list_formats(AVFormatContext *avctx, >>>decklink_direction_t direct >>> >>> av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", >>> avctx->filename); >>>+ if (ff_decklink_device_autodetect(avctx)) { >>>+ av_log(avctx, AV_LOG_INFO, "\t-1\tAuto detection supported\n"); >>>+ } >>> while (itermode->Next(&mode) == S_OK) { >>> BMDTimeValue tb_num, tb_den; >>> mode->GetFrameRate(&tb_num, &tb_den); >>>diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h >>>index dff4fc1..cbe8de2 100644 >>>--- a/libavdevice/decklink_common.h >>>+++ b/libavdevice/decklink_common.h >>>@@ -84,6 +84,8 @@ struct decklink_ctx { >>> sem_t semaphore; >>> >>> int channels; >>>+ int mode_num; >>>+ int auto_detect; >>> }; >>> >>> typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; >>>@@ -105,5 +107,8 @@ int ff_decklink_set_format(AVFormatContext *avctx, int >>>width, int height, int tb >>> 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); >>>+int ff_decklink_device_autodetect(AVFormatContext *avctx); >>>+int ff_decklink_mode_to_ffmpeg(AVFormatContext *avctx, decklink_direction_t >>>direction, IDeckLinkDisplayMode **mode); >>>+long ff_decklink_mode_to_bm(AVFormatContext *avctx, decklink_direction_t >>>direction, int ffmpeg_mode, IDeckLinkDisplayMode **mode); >>> >>> #endif /* AVDEVICE_DECKLINK_COMMON_H */ >>>diff --git a/libavdevice/decklink_common_c.h >>>b/libavdevice/decklink_common_c.h >>>index 2b5d92f..0d365be 100644 >>>--- a/libavdevice/decklink_common_c.h >>>+++ b/libavdevice/decklink_common_c.h >>>@@ -34,6 +34,7 @@ struct decklink_cctx { >>> double preroll; >>> int v210; >>> int audio_channels; >>>+ int autodetect_delay; >>> }; >>> >>> #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ >>>diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >>>index 1c305f3..552edc2 100644 >>>--- a/libavdevice/decklink_dec.cpp >>>+++ b/libavdevice/decklink_dec.cpp >>>@@ -1,5 +1,5 @@ >>> /* >>>- * Blackmagic DeckLink output >>>+ * Blackmagic DeckLink input >>> * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl >>> * >>> * This file is part of FFmpeg. >>>@@ -244,6 +244,12 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >>> BMDTimeValue frameTime; >>> BMDTimeValue frameDuration; >>> >>>+ /* if we don't have video, we are in the autodetect phase. skip >>>everything and let >>>+ * autodetect do its magic */ >>>+ if (!ctx->video) { >>>+ return S_OK; >>>+ } >>>+ >>> ctx->frameCount++; >>> >>> // Handle Video Frame >>>@@ -393,6 +399,14 @@ HRESULT >>>decklink_input_callback::VideoInputFormatChanged( >>> BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, >>> BMDDetectedVideoInputFormatFlags) >>> { >>>+ >>>+ /* undo all the autodetect stuff so we can move on with life */ >>>+ ctx->dli->PauseStreams(); >>>+ ctx->dli->FlushStreams(); >>>+ >>>+ ctx->mode_num = ff_decklink_mode_to_ffmpeg(avctx, DIRECTION_IN, &mode); >>>+ ctx->video = 1; >>>+ >>> return S_OK; >>> } >>> >>>@@ -435,14 +449,14 @@ av_cold int ff_decklink_read_header(AVFormatContext >>>*avctx) >>> { >>> struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; >>> struct decklink_ctx *ctx; >>>- IDeckLinkDisplayModeIterator *itermode; >>> IDeckLinkIterator *iter; >>> IDeckLink *dl = NULL; >>> AVStream *st; >>> HRESULT result; >>> char fname[1024]; >>> char *tmp; >>>- int mode_num = 0; >>>+ int auto_detect = 0; >>>+ unsigned int autodetect_delay = cctx->autodetect_delay; >>> >>> ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx)); >>> if (!ctx) >>>@@ -486,7 +500,7 @@ av_cold int ff_decklink_read_header(AVFormatContext >>>*avctx) >>> strcpy (fname, avctx->filename); >>> tmp=strchr (fname, '@'); >>> if (tmp != NULL) { >>>- mode_num = atoi (tmp+1); >>>+ ctx->mode_num = atoi (tmp+1); >>> *tmp = 0; >>> } >>> >>>@@ -510,34 +524,74 @@ av_cold int ff_decklink_read_header(AVFormatContext >>>*avctx) >>> >>> /* Get input device. */ >>> if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != >>> S_OK) { >>>- av_log(avctx, AV_LOG_ERROR, "Could not open output device from >>>'%s'\n", >>>+ av_log(avctx, AV_LOG_ERROR, "Could not open input device from >>>'%s'\n", >>> avctx->filename); >>> ctx->dl->Release(); >>> return AVERROR(EIO); >>> } >>> >>>+ auto_detect = ff_decklink_device_autodetect(avctx); >>>+ >>> /* List supported formats. */ >>>- if (ctx->list_formats) { >>>+ if (ctx->list_formats || (ctx->mode_num <= 0 && !auto_detect)) { >>> ff_decklink_list_formats(avctx, DIRECTION_IN); >>> ctx->dli->Release(); >>> ctx->dl->Release(); >>> return AVERROR_EXIT; >>> } >>> >>>- if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) { >>>- av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode >>>Iterator\n"); >>>- ctx->dl->Release(); >>>- return AVERROR(EIO); >>>- } >>>+ if (ctx->mode_num <= 0 && auto_detect) { >>>+ /* the user is wanting to auto detect the mode. we need to fake out >>>the api and not start ffmpeg fully in this mode!*/ >>>+ ctx->auto_detect = 1; >>>+ ctx->mode_num = 1; /* it is assumed that there is at least one mode >>>supported on a decklink card. */ >>>+ >>>+ if (ff_decklink_set_format(avctx, DIRECTION_IN, ctx->mode_num) < 0) >>>{ >>>+ av_log(avctx, AV_LOG_ERROR, "Could not set mode %d\n", >>>ctx->mode_num); >>>+ goto error; >>>+ } >>> >>>- if (mode_num > 0) { >>>- if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) { >>>- av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", >>>mode_num, fname); >>>+ ctx->bmd_mode = ff_decklink_mode_to_bm(avctx, DIRECTION_IN, >>>ctx->mode_num, NULL); >>>+ result = ctx->dli->EnableVideoInput(ctx->bmd_mode, >>>+ cctx->v210 ? bmdFormat10BitYUV >>>: bmdFormat8BitYUV, >>>+ bmdVideoInputFlagDefault | >>>bmdVideoInputEnableFormatDetection); >>>+ if (result != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not enable video in the >>>pre-startup autodectect mode\n"); >>> goto error; >>> } >>>+ >>>+ result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, >>>bmdAudioSampleType16bitInteger, cctx->audio_channels); >>>+ if (result != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not enable audio in the >>>pre-startup autodetect mode\n"); >>>+ goto error; >>>+ } >>>+ >>>+ result = decklink_start_input(avctx); >>>+ if (result != S_OK) { >>>+ av_log(avctx, AV_LOG_ERROR, "Could not start input in the >>>pre-startup autodetect mode\n"); >>>+ goto error; >>>+ } >>>+ >>>+ /* we need to give the auto detect code some time to figure out >>>what mode we are really in */ >>>+ autodetect_delay = cctx->autodetect_delay; >>>+ while (!ctx->video) { >>>+ if (autodetect_delay--) { >>>+ /* this could indicate we are in the right mode. let's >>>assume so */ >>>+ break; >>>+ } >>>+ /* sleep for 1 second */ >>>+ av_usleep(100000); >>>+ } >>> } >>> >>>- itermode->Release(); >>>+ /* regardless as to if we did autodetect or not, we should now be in a >>>position to >>>+ * continue on as before with all the right setup to ensure we get the >>>right mode */ >>>+ ctx->video = 1; >>>+ if (ctx->mode_num > 0) { >>>+ if (ff_decklink_set_format(avctx, DIRECTION_IN, ctx->mode_num) < 0) >>>{ >>>+ av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", >>>ctx->mode_num, fname); >>>+ goto error; >>>+ } >>>+ } >>> >>> /* Setup streams. */ >>> st = avformat_new_stream(avctx, NULL); >>>@@ -618,6 +672,7 @@ av_cold int ff_decklink_read_header(AVFormatContext >>>*avctx) >>> >>> return 0; >>> >>>+ >>> error: >>> >>> ctx->dli->Release(); >>>diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c >>>index 40c21a7..3f83f8f 100644 >>>--- a/libavdevice/decklink_dec_c.c >>>+++ b/libavdevice/decklink_dec_c.c >>>@@ -36,6 +36,7 @@ static const AVOption options[] = { >>> { "standard", NULL, 0, >>> AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, >>> { "all", NULL, 0, >>> AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, >>> { "channels", "number of audio channels", OFFSET(audio_channels), >>> AV_OPT_TYPE_INT , { .i64 = 2 }, 2, 16, DEC }, >>>+ { "autodetect_delay", "number of seconds to wait for autodetect to >>>complete", OFFSET(autodetect_delay), AV_OPT_TYPE_INT , { .i64 = 5 }, 1, >>>30, DEC }, >>> { NULL }, >>> }; >>> >>>-- >>>2.7.4 >>> >>> >>> >>> >>>On 5/12/16, 3:10 PM, "ffmpeg-devel on behalf of Felt, Patrick" >>><ffmpeg-devel-boun...@ffmpeg.org on behalf of patrick.f...@echostar.com> >>>wrote: >>> >>>>Ah… I see a bug. I should either be setting ctx->video in the if block or >>>>I should be breaking instead of continuing. Good catch! >>>> >>>> >>>>On 5/12/16, 1:32 PM, "ffmpeg-devel on behalf of Matthias Hunstock" >>>><ffmpeg-devel-boun...@ffmpeg.org on behalf of a...@fem.tu-ilmenau.de> wrote: >>>> >>>>>Am 12.05.2016 um 19:16 schrieb Felt, Patrick: >>>>>> + while (!ctx->video) { >>>>>> + if (autodetect_delay--) { >>>>>> + /* this could indicate we are in the right mode. let's >>>>>> assume so */ >>>>>> + continue; >>>>>> + } >>>>>> + sleep(1); >>>>>> + } >>>>> >>>>>I don't get it. How does this loop sleep for autodetect_delay seconds? I >>>>>read it like "spin-loop for autodetect_delay times and then probe >>>>>ctx->video each second, possibly forever". >>>>> >>>>> >>>>> >>>>>_______________________________________________ >>>>>ffmpeg-devel mailing list >>>>>ffmpeg-devel@ffmpeg.org >>>>>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >>>> >>>>_______________________________________________ >>>>ffmpeg-devel mailing list >>>>ffmpeg-devel@ffmpeg.org >>>>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >>> >>>_______________________________________________ >>>ffmpeg-devel mailing list >>>ffmpeg-devel@ffmpeg.org >>>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >>_______________________________________________ >>ffmpeg-devel mailing list >>ffmpeg-devel@ffmpeg.org >>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > >_______________________________________________ >ffmpeg-devel mailing list >ffmpeg-devel@ffmpeg.org >http://ffmpeg.org/mailman/listinfo/ffmpeg-devel _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel