| 260 | } |
| 261 | |
| 262 | int ff_decklink_set_format(AVFormatContext *avctx, |
| 263 | int width, int height, |
| 264 | int tb_num, int tb_den, |
| 265 | enum AVFieldOrder field_order, |
| 266 | decklink_direction_t direction) |
| 267 | { |
| 268 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
| 269 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
| 270 | #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 |
| 271 | DECKLINK_BOOL support; |
| 272 | #else |
| 273 | BMDDisplayModeSupport support; |
| 274 | #endif |
| 275 | IDeckLinkDisplayModeIterator *itermode; |
| 276 | IDeckLinkDisplayMode *mode; |
| 277 | int i = 1; |
| 278 | HRESULT res; |
| 279 | |
| 280 | av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, format code %s\n", |
| 281 | width, height, tb_num, tb_den, field_order, direction, cctx->format_code ? cctx->format_code : "(unset)"); |
| 282 | |
| 283 | if (direction == DIRECTION_IN) { |
| 284 | res = ctx->dli->GetDisplayModeIterator (&itermode); |
| 285 | } else { |
| 286 | res = ctx->dlo->GetDisplayModeIterator (&itermode); |
| 287 | } |
| 288 | |
| 289 | if (res!= S_OK) { |
| 290 | av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); |
| 291 | return AVERROR(EIO); |
| 292 | } |
| 293 | |
| 294 | char format_buf[] = " "; |
| 295 | if (cctx->format_code) |
| 296 | memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf))); |
| 297 | BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf); |
| 298 | AVRational target_tb = av_make_q(tb_num, tb_den); |
| 299 | ctx->bmd_mode = bmdModeUnknown; |
| 300 | while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) { |
| 301 | BMDTimeValue bmd_tb_num, bmd_tb_den; |
| 302 | int bmd_width = mode->GetWidth(); |
| 303 | int bmd_height = mode->GetHeight(); |
| 304 | BMDDisplayMode bmd_mode = mode->GetDisplayMode(); |
| 305 | BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance(); |
| 306 | |
| 307 | mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); |
| 308 | AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den); |
| 309 | |
| 310 | if ((bmd_width == width && |
| 311 | bmd_height == height && |
| 312 | !av_cmp_q(mode_tb, target_tb) && |
| 313 | field_order_eq(field_order, bmd_field_dominance)) |
| 314 | || target_mode == bmd_mode) { |
| 315 | ctx->bmd_mode = bmd_mode; |
| 316 | ctx->bmd_width = bmd_width; |
| 317 | ctx->bmd_height = bmd_height; |
| 318 | ctx->bmd_tb_den = bmd_tb_den; |
| 319 | ctx->bmd_tb_num = bmd_tb_num; |