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

Reply via email to