| 195 | }; |
| 196 | |
| 197 | static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) |
| 198 | { |
| 199 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
| 200 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
| 201 | AVCodecParameters *c = st->codecpar; |
| 202 | |
| 203 | if (ctx->video) { |
| 204 | av_log(avctx, AV_LOG_ERROR, "Only one video stream is supported!\n"); |
| 205 | return -1; |
| 206 | } |
| 207 | |
| 208 | if (c->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { |
| 209 | if (c->format != AV_PIX_FMT_UYVY422) { |
| 210 | av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format!" |
| 211 | " Only AV_PIX_FMT_UYVY422 is supported.\n"); |
| 212 | return -1; |
| 213 | } |
| 214 | ctx->raw_format = bmdFormat8BitYUV; |
| 215 | } else if (c->codec_id != AV_CODEC_ID_V210) { |
| 216 | av_log(avctx, AV_LOG_ERROR, "Unsupported codec type!" |
| 217 | " Only V210 and wrapped frame with AV_PIX_FMT_UYVY422 are supported.\n"); |
| 218 | return -1; |
| 219 | } else { |
| 220 | ctx->raw_format = bmdFormat10BitYUV; |
| 221 | } |
| 222 | |
| 223 | if (ff_decklink_set_configs(avctx, DIRECTION_OUT) < 0) { |
| 224 | av_log(avctx, AV_LOG_ERROR, "Could not set output configuration\n"); |
| 225 | return -1; |
| 226 | } |
| 227 | if (ff_decklink_set_format(avctx, c->width, c->height, |
| 228 | st->time_base.num, st->time_base.den, c->field_order)) { |
| 229 | av_log(avctx, AV_LOG_ERROR, "Unsupported video size, framerate or field order!" |
| 230 | " Check available formats with -list_formats 1.\n"); |
| 231 | return -1; |
| 232 | } |
| 233 | if (ctx->supports_vanc && ctx->dlo->EnableVideoOutput(ctx->bmd_mode, bmdVideoOutputVANC) != S_OK) { |
| 234 | av_log(avctx, AV_LOG_WARNING, "Could not enable video output with VANC! Trying without...\n"); |
| 235 | ctx->supports_vanc = 0; |
| 236 | } |
| 237 | if (!ctx->supports_vanc && ctx->dlo->EnableVideoOutput(ctx->bmd_mode, bmdVideoOutputFlagDefault) != S_OK) { |
| 238 | av_log(avctx, AV_LOG_ERROR, "Could not enable video output!\n"); |
| 239 | return -1; |
| 240 | } |
| 241 | |
| 242 | /* Set callback. */ |
| 243 | ctx->output_callback = new decklink_output_callback(); |
| 244 | ctx->dlo->SetScheduledFrameCompletionCallback(ctx->output_callback); |
| 245 | |
| 246 | ctx->frames_preroll = st->time_base.den * ctx->preroll; |
| 247 | if (st->time_base.den > 1000) |
| 248 | ctx->frames_preroll /= 1000; |
| 249 | |
| 250 | /* Buffer twice as many frames as the preroll. */ |
| 251 | ctx->frames_buffer = ctx->frames_preroll * 2; |
| 252 | ctx->frames_buffer = FFMIN(ctx->frames_buffer, 60); |
| 253 | pthread_mutex_init(&ctx->mutex, NULL); |
| 254 | pthread_cond_init(&ctx->cond, NULL); |
no test coverage detected