On Tue, 7 Nov 2017, Jeyapal, Karthick wrote:

On 11/6/17, 6:19 AM, "Marton Balint" <c...@passwd.hu> wrote:

On Fri, 27 Oct 2017, Jeyapal, Karthick wrote:

Please find the patch attached.


Thanks, below some comments:

Thanks a lot for your detailed comments. I have incorporated all your comments 
in this new patch(es).
Also, I have split it as two patches as you suggested. Please find them 
attached.

For the first patch, I think you forgot to call ff_decklink_set_configs in decklink_enc.

For the second patch here are some comments:

From 041bed1ef07e59419f1befda3f064f0fe3f8e30b Mon Sep 17 00:00:00 2001
From: Karthick J <kjeya...@akamai.com>
Date: Fri, 27 Oct 2017 12:00:23 +0530
Subject: [PATCH 2/2] libavdevice/decklink_dec: Autodetect the video input
 format

When -format_code is not specified autodetection will happen
---
 doc/indevs.texi                 |  2 ++
 libavdevice/decklink_common.cpp |  3 --
 libavdevice/decklink_common.h   |  1 +
 libavdevice/decklink_common_c.h |  6 ++++
 libavdevice/decklink_dec.cpp    | 78 ++++++++++++++++++++++++++++++++++-------
 5 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index d308bbf..56066bf 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -238,6 +238,8 @@ This sets the input video format to the format given by the 
FourCC. To see
 the supported values of your device(s) use @option{list_formats}.
 Note that there is a FourCC @option{'pal '} that can also be used
 as @option{pal} (3 letters).
+Default behavior is autodetection of the input video format, if the hardware
+supports it.

 @item bm_v210
 This is a deprecated option, you can use @option{raw_format} instead.
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
index b952e74..6ef2c52 100644
--- a/libavdevice/decklink_common.cpp
+++ b/libavdevice/decklink_common.cpp
@@ -75,7 +75,6 @@ static char *dup_wchar_to_utf8(wchar_t *w)
 #define DECKLINK_STR    OLECHAR *
 #define DECKLINK_STRDUP dup_wchar_to_utf8
 #define DECKLINK_FREE(s) SysFreeString(s)
-#define DECKLINK_BOOL BOOL
 #elif defined(__APPLE__)
 static char *dup_cfstring_to_utf8(CFStringRef w)
 {
@@ -86,13 +85,11 @@ static char *dup_cfstring_to_utf8(CFStringRef w)
 #define DECKLINK_STR    const __CFString *
 #define DECKLINK_STRDUP dup_cfstring_to_utf8
 #define DECKLINK_FREE(s) CFRelease(s)
-#define DECKLINK_BOOL bool
 #else
 #define DECKLINK_STR    const char *
 #define DECKLINK_STRDUP av_strdup
 /* free() is needed for a string returned by the DeckLink SDL. */
 #define DECKLINK_FREE(s) free((void *) s)
-#define DECKLINK_BOOL bool
 #endif

 HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName)
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 4345156..d18b643 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -95,6 +95,7 @@ struct decklink_ctx {
     pthread_mutex_t mutex;
     pthread_cond_t cond;
     int frames_buffer_available_spots;
+    int autodetect;

     int channels;
     int audio_depth;
diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
index 368ac25..4e4c369 100644
--- a/libavdevice/decklink_common_c.h
+++ b/libavdevice/decklink_common_c.h
@@ -23,6 +23,12 @@
 #ifndef AVDEVICE_DECKLINK_COMMON_C_H
 #define AVDEVICE_DECKLINK_COMMON_C_H

+#ifdef _WIN32
+#define DECKLINK_BOOL BOOL
+#else
+#define DECKLINK_BOOL bool
+#endif
+

This rather belongs to decklink_common.h.

 typedef enum DecklinkPtsSource {
     PTS_SRC_AUDIO     = 1,
     PTS_SRC_VIDEO     = 2,
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 242a194..60017e4 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -36,6 +36,7 @@ extern "C" {
 #include "libavutil/avutil.h"
 #include "libavutil/common.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/time.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/reverse.h"
@@ -49,6 +50,7 @@ extern "C" {
 #include "decklink_dec.h"

 #define MAX_WIDTH_VANC 1920
+const BMDDisplayMode AUTODETECT_DEFAULT_MODE = bmdModeNTSC;

 typedef struct VANCLineNumber {
     BMDDisplayMode mode;
@@ -634,6 +636,17 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
     BMDTimeValue frameDuration;
     int64_t wallclock = 0;

+    if (ctx->autodetect) {
+        pthread_mutex_lock(&ctx->mutex);

Do you still need a mutex? VideoInputFrameArrived and
VideoInputFormatChanged are called from the same thread, no?

+        if (videoFrame && !(videoFrame->GetFlags() & bmdFrameHasNoInputSource) 
&&
+            ctx->bmd_mode == bmdModeUnknown)
+        {
+            ctx->bmd_mode = AUTODETECT_DEFAULT_MODE;
+        }
+        pthread_mutex_unlock(&ctx->mutex);
+        return S_OK;
+    }
+
     ctx->frameCount++;
     if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == 
PTS_SRC_WALLCLOCK)
         wallclock = av_gettime_relative();
@@ -794,17 +807,47 @@ HRESULT decklink_input_callback::VideoInputFormatChanged(
     BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
     BMDDetectedVideoInputFormatFlags)
 {
+    pthread_mutex_lock(&ctx->mutex);
+    ctx->bmd_mode  = mode->GetDisplayMode();
+    pthread_mutex_unlock(&ctx->mutex);
     return S_OK;
 }

-static HRESULT decklink_start_input(AVFormatContext *avctx)
-{
-    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
+static int decklink_autodetect(struct decklink_cctx *cctx) {
     struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
+    DECKLINK_BOOL autodetect_supported = false;
+
+
+    if (ctx->attr->GetFlag(BMDDeckLinkSupportsInputFormatDetection, 
&autodetect_supported) != S_OK)
+        return -1;
+    if (autodetect_supported == false)
+        return -1;
+
+    ctx->autodetect = 1;
+    ctx->bmd_mode  = bmdModeUnknown;
+    if (ctx->dli->EnableVideoInput(AUTODETECT_DEFAULT_MODE,
+                                   bmdFormat8BitYUV,
+                                   bmdVideoInputEnableFormatDetection) != 
S_OK) {
+        return -1;
+    }
+
+    if (ctx->dli->StartStreams() != S_OK) {
+        return -1;
+    }
+
+    av_usleep(1000000); // 1 second timeout for any input frames to arrive

Have you considered something like:
for (i = 0; i < 25; i++) {
   av_usleep(40000);
   if (ctx->bmd_mode != bmdModeUnknown)
       break;
}

+
+    ctx->dli->PauseStreams();
+    ctx->dli->FlushStreams();
+    ctx->autodetect = 0;
+    if (ctx->bmd_mode != bmdModeUnknown) {
+        cctx->format_code = (char *)av_calloc(1, 5);

av_mallocz(5)
Missing failure check.

+        AV_WB32(cctx->format_code, ctx->bmd_mode);
+        return 0;
+    } else {
+        return -1;
+    }

-    ctx->input_callback = new decklink_input_callback(avctx);
-    ctx->dli->SetCallback(ctx->input_callback);
-    return ctx->dli->StartStreams();
 }

 extern "C" {
@@ -916,19 +959,30 @@ av_cold int ff_decklink_read_header(AVFormatContext 
*avctx)
         goto error;
     }

+    avpacket_queue_init (avctx, &ctx->queue);
+
+    ctx->input_callback = new decklink_input_callback(avctx);
+    ctx->dli->SetCallback(ctx->input_callback);
+

I'd rather put these after ff_decklink_set_configs.

     if (ff_decklink_set_configs(avctx, DIRECTION_IN) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not set input configuration\n");
         ret = AVERROR(EIO);
         goto error;
     }

-    if (mode_num > 0 || cctx->format_code) {
-        if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "Could not set mode number %d or format 
code %s for %s\n",
-                mode_num, (cctx->format_code) ? cctx->format_code : "(unset)", 
fname);
+    if (mode_num == 0 && !cctx->format_code) {
+        if (decklink_autodetect(cctx) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No 
signal\n");
             ret = AVERROR(EIO);
             goto error;
         }
+        av_log(avctx, AV_LOG_INFO, "Autodetected the input mode\n");
+    }
+    if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not set mode number %d or format code %s 
for %s\n",
+            mode_num, (cctx->format_code) ? cctx->format_code : "(unset)", 
fname);
+        ret = AVERROR(EIO);
+        goto error;
     }

 #if !CONFIG_LIBZVBI
@@ -1056,9 +1110,7 @@ av_cold int ff_decklink_read_header(AVFormatContext 
*avctx)
         goto error;
     }

-    avpacket_queue_init (avctx, &ctx->queue);
-
-    if (decklink_start_input (avctx) != S_OK) {
+    if (ctx->dli->StartStreams() != S_OK) {
         av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
         ret = AVERROR(EIO);
         goto error;
--
1.9.1


Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to