int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs){ IDeckLink *dl = NULL; IDeckLinkIterator *iter = decklink_create_iterator(avctx); int ret = 0; if (!iter) return AVERROR(EIO); while (ret == 0 && iter->Next(&dl) == S_OK) { IDeckLinkOutput *output_config; IDeckLinkInput *input_config; const char *display_name = NULL; const char *unique_name = NULL; AVDeviceInfo *new_device = NULL; int add = 0; ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name); if (ret < 0) goto next; ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name); if (ret < 0) goto next; 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(unique_name ? unique_name : display_name); new_device->device_description = av_strdup(display_name); if (!new_device->device_name || !new_device->device_description || av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) { ret = AVERROR(ENOMEM); av_freep(&new_device->device_name); av_freep(&new_device->device_description); av_freep(&new_device); goto next; } } next: av_freep(&display_name); av_freep(&unique_name); dl->Release(); } iter->Release(); 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_description); } } avdevice_free_list_devices(&device_list);} 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; uint32_t format_code; HRESULT res; if (direction == DIRECTION_IN) { int ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection); if (ret < 0) return ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection); if (ret < 0) return ret; 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\tformat_code\tdescription", avctx->url); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); format_code = av_bswap32(mode->GetDisplayMode()); av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps", (char*) &format_code, 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; } mode->Release(); } av_log(avctx, AV_LOG_INFO, "\n"); itermode->Release(); return 0;} void ff_decklink_cleanup(AVFormatContext *avctx){ struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; if (ctx->dli) ctx->dli->Release(); if (ctx->dlo) ctx->dlo->Release(); if (ctx->attr) ctx->attr->Release(); if (ctx->cfg) ctx->cfg->Release(); if (ctx->dl) ctx->dl->Release();} int ff_decklink_init_device(AVFormatContext *avctx, const char* name){ struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; IDeckLink *dl = NULL; IDeckLinkIterator *iter = decklink_create_iterator(avctx); if (!iter) return AVERROR_EXTERNAL; while (iter->Next(&dl) == S_OK) { const char *display_name = NULL; const char *unique_name = NULL; decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name); decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name); if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) { av_free((void *)unique_name); av_free((void *)display_name); ctx->dl = dl; break; } av_free((void *)display_name); av_free((void *)unique_name); dl->Release(); } iter->Release(); if (!ctx->dl) return AVERROR(ENXIO); if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name); ff_decklink_cleanup(avctx); return AVERROR_EXTERNAL; } if (ctx->dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&ctx->attr) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name); ff_decklink_cleanup(avctx); return AVERROR_EXTERNAL; } return 0;}Lines 501–706 of 706. Previous lines
int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs) { IDeckLink *dl = NULL; IDeckLinkIterator *iter = decklink_create_iterator(avctx); int ret = 0; if (!iter) return AVERROR(EIO); while (ret == 0 && iter->Next(&dl) == S_OK) { IDeckLinkOutput *output_config; IDeckLinkInput *input_config; const char *display_name = NULL; const char *unique_name = NULL; AVDeviceInfo *new_device = NULL; int add = 0; ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name); if (ret < 0) goto next; ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name); if (ret < 0) goto next; 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(unique_name ? unique_name : display_name); new_device->device_description = av_strdup(display_name); if (!new_device->device_name || !new_device->device_description || av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) { ret = AVERROR(ENOMEM); av_freep(&new_device->device_name); av_freep(&new_device->device_description); av_freep(&new_device); goto next; } } next: av_freep(&display_name); av_freep(&unique_name); dl->Release(); } iter->Release(); 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_description); } } avdevice_free_list_devices(&device_list); } 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; uint32_t format_code; HRESULT res; if (direction == DIRECTION_IN) { int ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection); if (ret < 0) return ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection); if (ret < 0) return ret; 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\tformat_code\tdescription", avctx->url); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); format_code = av_bswap32(mode->GetDisplayMode()); av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps", (char*) &format_code, 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; } mode->Release(); } av_log(avctx, AV_LOG_INFO, "\n"); itermode->Release(); return 0; } void ff_decklink_cleanup(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; if (ctx->dli) ctx->dli->Release(); if (ctx->dlo) ctx->dlo->Release(); if (ctx->attr) ctx->attr->Release(); if (ctx->cfg) ctx->cfg->Release(); if (ctx->dl) ctx->dl->Release(); } int ff_decklink_init_device(AVFormatContext *avctx, const char* name) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; IDeckLink *dl = NULL; IDeckLinkIterator *iter = decklink_create_iterator(avctx); if (!iter) return AVERROR_EXTERNAL; while (iter->Next(&dl) == S_OK) { const char *display_name = NULL; const char *unique_name = NULL; decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name); decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name); if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) { av_free((void *)unique_name); av_free((void *)display_name); ctx->dl = dl; break; } av_free((void *)display_name); av_free((void *)unique_name); dl->Release(); } iter->Release(); if (!ctx->dl) return AVERROR(ENXIO); if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name); ff_decklink_cleanup(avctx); return AVERROR_EXTERNAL; } if (ctx->dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&ctx->attr) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name); ff_decklink_cleanup(avctx); return AVERROR_EXTERNAL; } return 0; }