diff options
author | Deti Fliegl <deti@fliegl.de> | 2014-09-22 03:39:50 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-09-22 03:39:50 +0400 |
commit | a5e040ee3c757f4673e3c7202e823490593f21d7 (patch) | |
tree | 2f50e968b94ee3af5ae8ecbfb7249d8d582ae186 | |
parent | 56b8d106769c5c5f9174dcc426f1ee2f991428b1 (diff) |
avdevice/decklink: move general code of decklink encoder to common file
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavdevice/Makefile | 4 | ||||
-rw-r--r-- | libavdevice/decklink_common.cpp | 229 | ||||
-rw-r--r-- | libavdevice/decklink_common.h | 98 | ||||
-rw-r--r-- | libavdevice/decklink_common_c.h | 32 | ||||
-rw-r--r-- | libavdevice/decklink_enc.cpp | 198 | ||||
-rw-r--r-- | libavdevice/decklink_enc.h | 11 | ||||
-rw-r--r-- | libavdevice/decklink_enc_c.c | 1 |
7 files changed, 380 insertions, 193 deletions
diff --git a/libavdevice/Makefile b/libavdevice/Makefile index db301e7112..f90c0f73c7 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -16,7 +16,7 @@ OBJS-$(CONFIG_ALSA_OUTDEV) += alsa-audio-common.o \ OBJS-$(CONFIG_AVFOUNDATION_INDEV) += avfoundation.o OBJS-$(CONFIG_BKTR_INDEV) += bktr.o OBJS-$(CONFIG_CACA_OUTDEV) += caca.o -OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o +OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o decklink_common.o OBJS-$(CONFIG_DSHOW_INDEV) += dshow.o dshow_enummediatypes.o \ dshow_enumpins.o dshow_filter.o \ dshow_pin.o dshow_common.o @@ -57,7 +57,7 @@ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o # Windows resource file SLIBOBJS-$(HAVE_GNU_WINDRES) += avdeviceres.o -SKIPHEADERS-$(CONFIG_DECKLINK) += decklink_enc.h +SKIPHEADERS-$(CONFIG_DECKLINK) += decklink_enc.h decklink_common.h SKIPHEADERS-$(CONFIG_DSHOW_INDEV) += dshow_capture.h SKIPHEADERS-$(CONFIG_FBDEV_INDEV) += fbdev_common.h SKIPHEADERS-$(CONFIG_FBDEV_OUTDEV) += fbdev_common.h diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp new file mode 100644 index 0000000000..9a9e44bf3c --- /dev/null +++ b/libavdevice/decklink_common.cpp @@ -0,0 +1,229 @@ +/* + * Blackmagic DeckLink output + * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <DeckLinkAPI.h> +#ifdef _WIN32 +#include <DeckLinkAPI_i.c> +#else +#include <DeckLinkAPIDispatch.cpp> +#endif + +#include <pthread.h> +#include <semaphore.h> + +extern "C" { +#include "libavformat/avformat.h" +#include "libavformat/internal.h" +#include "libavutil/imgutils.h" +} + +#include "decklink_common.h" + +#ifdef _WIN32 +IDeckLinkIterator *CreateDeckLinkIteratorInstance(void) +{ + IDeckLinkIterator *iter; + + if (CoInitialize(NULL) != S_OK) { + av_log(NULL, AV_LOG_ERROR, "COM initialization failed.\n"); + return NULL; + } + + if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, + IID_IDeckLinkIterator, (void**) &iter) != S_OK) { + av_log(NULL, AV_LOG_ERROR, "DeckLink drivers not installed.\n"); + return NULL; + } + + return iter; +} +#endif + +#ifdef _WIN32 +static char *dup_wchar_to_utf8(wchar_t *w) +{ + char *s = NULL; + int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); + s = (char *) av_malloc(l); + if (s) + WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); + return s; +} +#define DECKLINK_STR OLECHAR * +#define DECKLINK_STRDUP dup_wchar_to_utf8 +#else +#define DECKLINK_STR const char * +#define DECKLINK_STRDUP av_strdup +#endif + +HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName) +{ + DECKLINK_STR tmpDisplayName; + HRESULT hr = This->GetDisplayName(&tmpDisplayName); + if (hr != S_OK) + return hr; + *displayName = DECKLINK_STRDUP(tmpDisplayName); + /* free() is needed for a string returned by the DeckLink SDL. */ + free((void *) tmpDisplayName); + return hr; +} + +int ff_decklink_set_format(AVFormatContext *avctx, + int width, int height, + int tb_num, int tb_den, + decklink_direction_t direction, int num) +{ + struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; + struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; + BMDDisplayModeSupport support; + IDeckLinkDisplayModeIterator *itermode; + IDeckLinkDisplayMode *mode; + int i = 1; + 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 Display Mode Iterator\n"); + return AVERROR(EIO); + } + + + if (tb_num == 1) { + tb_num *= 1000; + tb_den *= 1000; + } + ctx->bmd_mode = bmdModeUnknown; + while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) { + BMDTimeValue bmd_tb_num, bmd_tb_den; + int bmd_width = mode->GetWidth(); + int bmd_height = mode->GetHeight(); + + mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); + + if ((bmd_width == width && bmd_height == height && + bmd_tb_num == tb_num && bmd_tb_den == tb_den) || i == num) { + ctx->bmd_mode = mode->GetDisplayMode(); + ctx->bmd_width = bmd_width; + ctx->bmd_height = bmd_height; + ctx->bmd_tb_den = bmd_tb_den; + ctx->bmd_tb_num = bmd_tb_num; + ctx->bmd_field_dominance = mode->GetFieldDominance(); + av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n", + bmd_width, bmd_height, (float)bmd_tb_den/(float)bmd_tb_num, + (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":""); + } + + mode->Release(); + i++; + } + + itermode->Release(); + + if (ctx->bmd_mode == bmdModeUnknown) + return -1; + if (direction == DIRECTION_IN) { + if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, + bmdVideoOutputFlagDefault, + &support, NULL) != S_OK) + return -1; + } else { + if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, + bmdVideoOutputFlagDefault, + &support, NULL) != S_OK) + return -1; + } + if (support == bmdDisplayModeSupported) + return 0; + + return -1; +} + +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); +} + +int ff_decklink_list_devices(AVFormatContext *avctx) +{ + IDeckLink *dl = NULL; + IDeckLinkIterator *iter = CreateDeckLinkIteratorInstance(); + if (!iter) { + av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n"); + return AVERROR(EIO); + } + av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n"); + while (iter->Next(&dl) == S_OK) { + const char *displayName; + ff_decklink_get_display_name(dl, &displayName); + av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName); + av_free((void *) displayName); + dl->Release(); + } + iter->Release(); + return 0; +} + +int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) +{ + struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; + struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; + IDeckLinkDisplayModeIterator *itermode; + IDeckLinkDisplayMode *mode; + int i=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 Display Mode Iterator\n"); + return AVERROR(EIO); + } + + av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", + avctx->filename); + while (itermode->Next(&mode) == S_OK) { + BMDTimeValue tb_num, tb_den; + mode->GetFrameRate(&tb_num, &tb_den); + av_log(avctx, AV_LOG_INFO, "\t%d\t%ldx%ld at %d/%d fps", + ++i,mode->GetWidth(), mode->GetHeight(), + (int) tb_den, (int) tb_num); + switch (mode->GetFieldDominance()) { + case bmdLowerFieldFirst: + av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break; + case bmdUpperFieldFirst: + av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break; + } + av_log(avctx, AV_LOG_INFO, "\n"); + mode->Release(); + } + + itermode->Release(); + + return 0; +} diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h new file mode 100644 index 0000000000..544da27836 --- /dev/null +++ b/libavdevice/decklink_common.h @@ -0,0 +1,98 @@ +/* + * Blackmagic DeckLink common code + * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "decklink_common_c.h" + +class decklink_output_callback; +class decklink_input_callback; + +typedef struct AVPacketQueue { + AVPacketList *first_pkt, *last_pkt; + int nb_packets; + unsigned long long size; + int abort_request; + pthread_mutex_t mutex; + pthread_cond_t cond; + AVFormatContext *avctx; +} AVPacketQueue; + +struct decklink_ctx { + /* DeckLink SDK interfaces */ + IDeckLink *dl; + IDeckLinkOutput *dlo; + IDeckLinkInput *dli; + decklink_output_callback *output_callback; + decklink_input_callback *input_callback; + + /* DeckLink mode information */ + BMDTimeValue bmd_tb_den; + BMDTimeValue bmd_tb_num; + BMDDisplayMode bmd_mode; + int bmd_width; + int bmd_height; + int bmd_field_dominance; + + /* Capture buffer queue */ + AVPacketQueue queue; + + /* Streams present */ + int audio; + int video; + + /* Status */ + int playback_started; + int capture_started; + int64_t last_pts; + unsigned long frameCount; + unsigned int dropped; + AVStream *audio_st; + AVStream *video_st; + + /* Options */ + int list_devices; + int list_formats; + double preroll; + + int frames_preroll; + int frames_buffer; + + sem_t semaphore; + + int channels; +}; + +typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; + +#ifdef _WIN32 +typedef unsigned long buffercount_type; +IDeckLinkIterator *CreateDeckLinkIteratorInstance(void); +char *dup_wchar_to_utf8(wchar_t *w); +#else +typedef uint32_t buffercount_type; +#endif + + +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, 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); + diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h new file mode 100644 index 0000000000..861a51aa12 --- /dev/null +++ b/libavdevice/decklink_common_c.h @@ -0,0 +1,32 @@ +/* + * Blackmagic DeckLink common code + * Copyright (c) 2013-2014 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +struct decklink_cctx { + const AVClass *cclass; + + void *ctx; + + /* Options */ + int list_devices; + int list_formats; + double preroll; +}; + diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 3d7cbe237c..6c5450f4ec 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -20,13 +20,6 @@ */ #include <DeckLinkAPI.h> -#ifdef _WIN32 -#include <DeckLinkAPI_i.c> -typedef unsigned long buffercount_type; -#else -#include <DeckLinkAPIDispatch.cpp> -typedef uint32_t buffercount_type; -#endif #include <pthread.h> #include <semaphore.h> @@ -37,44 +30,9 @@ extern "C" { #include "libavutil/imgutils.h" } +#include "decklink_common.h" #include "decklink_enc.h" -class decklink_callback; - -struct decklink_ctx { - /* DeckLink SDK interfaces */ - IDeckLink *dl; - IDeckLinkOutput *dlo; - decklink_callback *callback; - - /* DeckLink mode information */ - IDeckLinkDisplayModeIterator *itermode; - BMDTimeValue bmd_tb_den; - BMDTimeValue bmd_tb_num; - BMDDisplayMode bmd_mode; - int bmd_width; - int bmd_height; - - /* Streams present */ - int audio; - int video; - - /* Status */ - int playback_started; - int64_t last_pts; - - /* Options */ - int list_devices; - int list_formats; - double preroll; - - int frames_preroll; - int frames_buffer; - - sem_t semaphore; - - int channels; -}; /* DeckLink callback class declaration */ class decklink_frame : public IDeckLinkVideoFrame @@ -109,7 +67,7 @@ private: int _refs; }; -class decklink_callback : public IDeckLinkVideoOutputCallback +class decklink_output_callback : public IDeckLinkVideoOutputCallback { public: virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame *_frame, BMDOutputFrameCompletionResult result) @@ -130,99 +88,6 @@ public: virtual ULONG STDMETHODCALLTYPE Release(void) { return 1; } }; -#ifdef _WIN32 -static IDeckLinkIterator *CreateDeckLinkIteratorInstance(void) -{ - IDeckLinkIterator *iter; - - if (CoInitialize(NULL) != S_OK) { - av_log(NULL, AV_LOG_ERROR, "COM initialization failed.\n"); - return NULL; - } - - if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, - IID_IDeckLinkIterator, (void**) &iter) != S_OK) { - av_log(NULL, AV_LOG_ERROR, "DeckLink drivers not installed.\n"); - return NULL; - } - - return iter; -} -#endif - -/* free() is needed for a string returned by the DeckLink SDL. */ -#undef free - -#ifdef _WIN32 -static char *dup_wchar_to_utf8(wchar_t *w) -{ - char *s = NULL; - int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); - s = (char *) av_malloc(l); - if (s) - WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); - return s; -} -#define DECKLINK_STR OLECHAR * -#define DECKLINK_STRDUP dup_wchar_to_utf8 -#else -#define DECKLINK_STR const char * -#define DECKLINK_STRDUP av_strdup -#endif - -static HRESULT IDeckLink_GetDisplayName(IDeckLink *This, const char **displayName) -{ - DECKLINK_STR tmpDisplayName; - HRESULT hr = This->GetDisplayName(&tmpDisplayName); - if (hr != S_OK) - return hr; - *displayName = DECKLINK_STRDUP(tmpDisplayName); - free((void *) tmpDisplayName); - return hr; -} - -static int decklink_set_format(struct decklink_ctx *ctx, - int width, int height, - int tb_num, int tb_den) -{ - BMDDisplayModeSupport support; - IDeckLinkDisplayMode *mode; - - if (tb_num == 1) { - tb_num *= 1000; - tb_den *= 1000; - } - ctx->bmd_mode = bmdModeUnknown; - while ((ctx->bmd_mode == bmdModeUnknown) && ctx->itermode->Next(&mode) == S_OK) { - BMDTimeValue bmd_tb_num, bmd_tb_den; - int bmd_width = mode->GetWidth(); - int bmd_height = mode->GetHeight(); - - mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); - - if (bmd_width == width && bmd_height == height && - bmd_tb_num == tb_num && bmd_tb_den == tb_den) { - ctx->bmd_mode = mode->GetDisplayMode(); - ctx->bmd_width = bmd_width; - ctx->bmd_height = bmd_height; - ctx->bmd_tb_den = bmd_tb_den; - ctx->bmd_tb_num = bmd_tb_num; - } - - mode->Release(); - } - if (ctx->bmd_mode == bmdModeUnknown) - return -1; - if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, - bmdVideoOutputFlagDefault, - &support, NULL) != S_OK) - return -1; - if (support == bmdDisplayModeSupported) - return 0; - - return -1; -} - static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; @@ -239,7 +104,7 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) " Only AV_PIX_FMT_UYVY422 is supported.\n"); return -1; } - if (decklink_set_format(ctx, c->width, c->height, + if (ff_decklink_set_format(avctx, c->width, c->height, c->time_base.num, c->time_base.den)) { av_log(avctx, AV_LOG_ERROR, "Unsupported video size or framerate!" " Check available formats with -list_formats 1.\n"); @@ -252,8 +117,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) } /* Set callback. */ - ctx->callback = new decklink_callback(); - ctx->dlo->SetScheduledFrameCompletionCallback(ctx->callback); + ctx->output_callback = new decklink_output_callback(); + ctx->dlo->SetScheduledFrameCompletionCallback(ctx->output_callback); /* Start video semaphore. */ ctx->frames_preroll = c->time_base.den * ctx->preroll; @@ -333,8 +198,8 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) if (ctx->dl) ctx->dl->Release(); - if (ctx->callback) - delete ctx->callback; + if (ctx->output_callback) + delete ctx->output_callback; sem_destroy(&ctx->semaphore); @@ -450,6 +315,7 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx; + IDeckLinkDisplayModeIterator *itermode; IDeckLinkIterator *iter; IDeckLink *dl = NULL; unsigned int n; @@ -470,22 +336,14 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) /* List available devices. */ if (ctx->list_devices) { - av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n"); - while (iter->Next(&dl) == S_OK) { - const char *displayName; - IDeckLink_GetDisplayName(dl, &displayName); - av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName); - av_free((void *) displayName); - dl->Release(); - } - iter->Release(); + ff_decklink_list_devices(avctx); return AVERROR_EXIT; } /* Open device. */ while (iter->Next(&dl) == S_OK) { const char *displayName; - IDeckLink_GetDisplayName(dl, &displayName); + ff_decklink_get_display_name(dl, &displayName); if (!strcmp(avctx->filename, displayName)) { av_free((void *) displayName); ctx->dl = dl; @@ -508,40 +366,20 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) return AVERROR(EIO); } - if (ctx->dlo->GetDisplayModeIterator(&ctx->itermode) != S_OK) { - av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); - ctx->dl->Release(); - return AVERROR(EIO); - } - /* List supported formats. */ if (ctx->list_formats) { - IDeckLinkDisplayMode *mode; - - av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", - avctx->filename); - while (ctx->itermode->Next(&mode) == S_OK) { - BMDTimeValue tb_num, tb_den; - mode->GetFrameRate(&tb_num, &tb_den); - av_log(avctx, AV_LOG_INFO, "\t%ldx%ld at %d/%d fps", - mode->GetWidth(), mode->GetHeight(), - (int) tb_den, (int) tb_num); - switch (mode->GetFieldDominance()) { - case bmdLowerFieldFirst: - av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break; - case bmdUpperFieldFirst: - av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break; - } - av_log(avctx, AV_LOG_INFO, "\n"); - mode->Release(); - } - - ctx->itermode->Release(); + ff_decklink_list_formats(avctx); ctx->dlo->Release(); ctx->dl->Release(); return AVERROR_EXIT; } + if (ctx->dlo->GetDisplayModeIterator(&itermode) != S_OK) { + av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); + ctx->dl->Release(); + return AVERROR(EIO); + } + /* Setup streams. */ for (n = 0; n < avctx->nb_streams; n++) { AVStream *st = avctx->streams[n]; @@ -557,7 +395,7 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) goto error; } } - ctx->itermode->Release(); + itermode->Release(); return 0; diff --git a/libavdevice/decklink_enc.h b/libavdevice/decklink_enc.h index 0b9ad8f79e..6086947e6c 100644 --- a/libavdevice/decklink_enc.h +++ b/libavdevice/decklink_enc.h @@ -19,17 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -struct decklink_cctx { - const AVClass *cclass; - - void *ctx; - - /* Options */ - int list_devices; - int list_formats; - double preroll; -}; - #ifdef __cplusplus extern "C" { #endif diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index 7c1804376a..c3c90184f8 100644 --- a/libavdevice/decklink_enc_c.c +++ b/libavdevice/decklink_enc_c.c @@ -22,6 +22,7 @@ #include "libavformat/avformat.h" #include "libavutil/opt.h" +#include "decklink_common_c.h" #include "decklink_enc.h" #define OFFSET(x) offsetof(struct decklink_cctx, x) |