From patchwork Fri Oct 6 12:55:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 5436 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.90 with SMTP id m26csp427517jah; Fri, 6 Oct 2017 05:56:13 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAPAKuYVhe1z3ZyH5bGq8WQoT4Xpm5BCP7dd8VVG0R+dGHDvlyc8cDlJBor5HaXdifwLEIo X-Received: by 10.28.46.16 with SMTP id u16mr1629689wmu.125.1507294573075; Fri, 06 Oct 2017 05:56:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507294573; cv=none; d=google.com; s=arc-20160816; b=EAk0E3AUB3z1CnGl+VG5CRfTlE+ocWbDtMOnBnoydEGqFb5+DdUZKtKQnnfx9oo5l0 maatT48WpCpHVmPNBIUMP0WIuCcN4MA4I6D/flQI1lmz3HYFu2DI2zujcpY384ut0Yrh Zrf7j/GrWL5zbsRm3vm9mC/5lCnNN4y+nPBgQn10RVBW3Uc/EsB73/OqDSTbPswtVgtr qT7W2Qj7kC2fkPpf4t7/ZDn/DSB6pvDHWAIARF8RVv2+ltzWJ8U17gMnoHOjNkL/AWaH tqE4sSAqB8Nztrk1ioL/aWnKtu3x8sBZKG77YmPmhchg6ugwYuMAHxr+YosLP06jzOZ2 ORHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:delivered-to:arc-authentication-results; bh=HAoaKpaB0geRvcDxPEyCYZ033ByUF9/B0SnHQ7W1C4c=; b=j8QkOKHEjcfaCxrQms3p8Er6QB7U+17DSfpcCnRUDwxVv1rlv7I+avA/OPZOldZEWx e5bFtoeDlKzOCfFJJ+R2FE4fZfP6yY1+7fIG15++Mie1tGBZfqH8sax4n+e8O5viJopi MIX6yk1aATHJB6wxh8wNrauQ4bSmnIVIPG5EO6vIoB00G7JtxuagShbtacx6uwhQgfCf +Q/U+5kJZpHMuDlLIQ1hpyIxjznSNQCKaub22N4OSDwcrtGEltypAA20jFPPWwiqb3bA h8tah+FwkFocrse7JOYz0zT0VQ0RxQi2K0BDYLHCUrac93ydxo0IB5g5uoDPMY+eAa8V csEg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 1si1320368wmo.138.2017.10.06.05.56.12; Fri, 06 Oct 2017 05:56:13 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B3B1B68A4C9; Fri, 6 Oct 2017 15:56:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from was-smtp1.livetimenet.net (50-206-97-56-static.hfc.comcastbusiness.net [50.206.97.56]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 23D7F68A20C for ; Fri, 6 Oct 2017 15:55:56 +0300 (EEST) Received: by was-smtp1.livetimenet.net with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.84_2) (envelope-from ) id 1e0SAV-0005Xp-5r; Fri, 06 Oct 2017 08:55:56 -0400 From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 6 Oct 2017 08:55:43 -0400 Message-Id: <20171006125544.35881-2-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20171006125544.35881-1-dheitmueller@ltnglobal.com> References: <20171006125544.35881-1-dheitmueller@ltnglobal.com> X-Spam-Score: -1.9 (-) Subject: [FFmpeg-devel] [PATCHv3 1/2] libavdevice/decklink: add support for -sources and -sinks arguments X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: jgreen@ltnglobal.com, Devin Heitmueller MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Add support for enumerating the sources/sinks via the ffmpeg command line options, as opposed to having to create a real pipeline and use the "-list_devices" option which does exit() after dumping out the options. Note that this patch preserves the existing "-list_devices" option, but now shares common code for the actual enumeration. Updated to reflect feedback from Marton Balint . Signed-off-by: Devin Heitmueller --- libavdevice/decklink_common.cpp | 89 ++++++++++++++++++++++++++++++++++++++--- libavdevice/decklink_common.h | 3 +- libavdevice/decklink_dec.cpp | 8 +++- libavdevice/decklink_dec.h | 1 + libavdevice/decklink_dec_c.c | 1 + libavdevice/decklink_enc.cpp | 10 ++++- libavdevice/decklink_enc.h | 1 + libavdevice/decklink_enc_c.c | 1 + 8 files changed, 104 insertions(+), 10 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index c782171f2c..61d8ad86a9 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -37,6 +37,7 @@ extern "C" { #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/bswap.h" +#include "avdevice.h" } #include "decklink_common.h" @@ -261,24 +262,100 @@ int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t directio return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction, num); } -int ff_decklink_list_devices(AVFormatContext *avctx) +int ff_decklink_list_devices(AVFormatContext *avctx, + struct AVDeviceInfoList *device_list, + int show_inputs, int show_outputs) { IDeckLink *dl = NULL; IDeckLinkIterator *iter = CreateDeckLinkIteratorInstance(); + int ret = 0; + 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) { + + while (ret == 0 && iter->Next(&dl) == S_OK) { + IDeckLinkOutput *output_config; + IDeckLinkInput *input_config; const char *displayName; + AVDeviceInfo *new_device = NULL; + int add = 0; + ff_decklink_get_display_name(dl, &displayName); - av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName); - av_free((void *) displayName); + + if (show_outputs) { + if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) { + output_config->Release(); + add = 1; + } + } + + if (show_inputs) { + if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) { + input_config->Release(); + add = 1; + } + } + + if (add == 1) { + new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo)); + if (!new_device) { + ret = AVERROR(ENOMEM); + goto next; + } + new_device->device_name = av_strdup(displayName); + if (!new_device->device_name) { + ret = AVERROR(ENOMEM); + goto next; + } + + new_device->device_description = av_strdup(displayName); + if (!new_device->device_description) { + av_freep(&new_device->device_name); + ret = AVERROR(ENOMEM); + goto next; + } + + if ((ret = av_dynarray_add_nofree(&device_list->devices, + &device_list->nb_devices, new_device)) < 0) { + av_freep(&new_device->device_name); + av_freep(&new_device->device_description); + av_freep(&new_device); + goto next; + } + } + + next: + av_freep(&displayName); dl->Release(); } iter->Release(); - return 0; + return ret; +} + +/* This is a wrapper around the ff_decklink_list_devices() which dumps the + output to av_log() and exits (for backward compatibility with the + "-list_devices" argument). */ +void ff_decklink_list_devices_legacy(AVFormatContext *avctx, + int show_inputs, int show_outputs) +{ + struct AVDeviceInfoList *device_list = NULL; + int ret; + + device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList)); + if (!device_list) + return; + + ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs); + if (ret == 0) { + av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n", + show_inputs ? "input" : "output"); + for (int i = 0; i < device_list->nb_devices; i++) { + av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_name); + } + } + avdevice_free_list_devices(&device_list); } int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 749eb0f8b8..6b2525fb53 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -135,7 +135,8 @@ static const BMDVideoConnection decklink_video_connection_map[] = { 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, enum AVFieldOrder field_order, 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_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs); +void ff_decklink_list_devices_legacy(AVFormatContext *avctx, int show_inputs, int show_outputs); int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT); void ff_decklink_cleanup(AVFormatContext *avctx); int ff_decklink_init_device(AVFormatContext *avctx, const char* name); diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index f496a58059..419259e467 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -39,6 +39,7 @@ extern "C" { #include "libavutil/time.h" #include "libavutil/mathematics.h" #include "libavutil/reverse.h" +#include "avdevice.h" #if CONFIG_LIBZVBI #include #endif @@ -868,7 +869,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) /* List available devices. */ if (ctx->list_devices) { - ff_decklink_list_devices(avctx); + ff_decklink_list_devices_legacy(avctx, 1, 0); return AVERROR_EXIT; } @@ -1063,4 +1064,9 @@ int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt) return 0; } +int ff_decklink_list_input_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list) +{ + return ff_decklink_list_devices(avctx, device_list, 1, 0); +} + } /* extern "C" */ diff --git a/libavdevice/decklink_dec.h b/libavdevice/decklink_dec.h index 9b71870deb..fbfbe6280e 100644 --- a/libavdevice/decklink_dec.h +++ b/libavdevice/decklink_dec.h @@ -29,6 +29,7 @@ extern "C" { int ff_decklink_read_header(AVFormatContext *avctx); int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt); int ff_decklink_read_close(AVFormatContext *avctx); +int ff_decklink_list_input_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list); #ifdef __cplusplus } /* extern "C" */ diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 8b6ff067bc..1127d23ada 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -89,6 +89,7 @@ AVInputFormat ff_decklink_demuxer = { .flags = AVFMT_NOFILE, .priv_class = &decklink_demuxer_class, .priv_data_size = sizeof(struct decklink_cctx), + .get_device_list = ff_decklink_list_input_devices, .read_header = ff_decklink_read_header, .read_packet = ff_decklink_read_packet, .read_close = ff_decklink_read_close, diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 25ce7d026c..0776741812 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -33,6 +33,7 @@ extern "C" { extern "C" { #include "libavformat/avformat.h" #include "libavutil/imgutils.h" +#include "avdevice.h" } #include "decklink_common.h" @@ -335,9 +336,9 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) ctx->preroll = cctx->preroll; cctx->ctx = ctx; - /* List available devices. */ + /* List available devices and exit. */ if (ctx->list_devices) { - ff_decklink_list_devices(avctx); + ff_decklink_list_devices_legacy(avctx, 0, 1); return AVERROR_EXIT; } @@ -400,4 +401,9 @@ int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt) return AVERROR(EIO); } +int ff_decklink_list_output_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list) +{ + return ff_decklink_list_devices(avctx, device_list, 0, 1); +} + } /* extern "C" */ diff --git a/libavdevice/decklink_enc.h b/libavdevice/decklink_enc.h index 5ffc05cd68..39237673b4 100644 --- a/libavdevice/decklink_enc.h +++ b/libavdevice/decklink_enc.h @@ -29,6 +29,7 @@ extern "C" { int ff_decklink_write_header(AVFormatContext *avctx); int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt); int ff_decklink_write_trailer(AVFormatContext *avctx); +int ff_decklink_list_output_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list); #ifdef __cplusplus } /* extern "C" */ diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index 03734f8507..360535cfda 100644 --- a/libavdevice/decklink_enc_c.c +++ b/libavdevice/decklink_enc_c.c @@ -49,6 +49,7 @@ AVOutputFormat ff_decklink_muxer = { .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, .subtitle_codec = AV_CODEC_ID_NONE, .flags = AVFMT_NOFILE, + .get_device_list = ff_decklink_list_output_devices, .priv_class = &decklink_muxer_class, .priv_data_size = sizeof(struct decklink_cctx), .write_header = ff_decklink_write_header,