mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avdevice/decklink_dec: autodetect the video input format
When -format_code is not specified autodetection will happen. Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
aa7b0329ff
commit
e8e9306b4f
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -28,6 +28,12 @@
|
||||
#include "libavutil/thread.h"
|
||||
#include "decklink_common_c.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DECKLINK_BOOL BOOL
|
||||
#else
|
||||
#define DECKLINK_BOOL bool
|
||||
#endif
|
||||
|
||||
class decklink_output_callback;
|
||||
class decklink_input_callback;
|
||||
|
||||
@ -95,6 +101,7 @@ struct decklink_ctx {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int frames_buffer_available_spots;
|
||||
int autodetect;
|
||||
|
||||
int channels;
|
||||
int audio_depth;
|
||||
|
@ -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,15 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
|
||||
BMDTimeValue frameDuration;
|
||||
int64_t wallclock = 0;
|
||||
|
||||
if (ctx->autodetect) {
|
||||
if (videoFrame && !(videoFrame->GetFlags() & bmdFrameHasNoInputSource) &&
|
||||
ctx->bmd_mode == bmdModeUnknown)
|
||||
{
|
||||
ctx->bmd_mode = AUTODETECT_DEFAULT_MODE;
|
||||
}
|
||||
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 +805,56 @@ HRESULT decklink_input_callback::VideoInputFormatChanged(
|
||||
BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
|
||||
BMDDetectedVideoInputFormatFlags)
|
||||
{
|
||||
ctx->bmd_mode = mode->GetDisplayMode();
|
||||
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;
|
||||
int i;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 1 second timeout
|
||||
for (i = 0; i < 10; i++) {
|
||||
av_usleep(100000);
|
||||
/* Sometimes VideoInputFrameArrived is called without the
|
||||
* bmdFrameHasNoInputSource flag before VideoInputFormatChanged.
|
||||
* So don't break for bmd_mode == AUTODETECT_DEFAULT_MODE. */
|
||||
if (ctx->bmd_mode != bmdModeUnknown &&
|
||||
ctx->bmd_mode != AUTODETECT_DEFAULT_MODE)
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->dli->PauseStreams();
|
||||
ctx->dli->FlushStreams();
|
||||
ctx->autodetect = 0;
|
||||
if (ctx->bmd_mode != bmdModeUnknown) {
|
||||
cctx->format_code = (char *)av_mallocz(5);
|
||||
if (!cctx->format_code)
|
||||
return -1;
|
||||
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" {
|
||||
@ -922,14 +972,23 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mode_num > 0 || cctx->format_code) {
|
||||
ctx->input_callback = new decklink_input_callback(avctx);
|
||||
ctx->dli->SetCallback(ctx->input_callback);
|
||||
|
||||
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
|
||||
if (ctx->teletext_lines && ctx->bmd_mode == bmdModePAL) {
|
||||
@ -1058,7 +1117,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user