History

avdevice/decklink_enc: don't take for granted that first frame to decklink output will be PTS 0

The existing code assumed that the first frame received by the decklink output would always be PTS zero. However if running in other timing modes than the default of CBR, items such as frame dropping at the beginning may result in starting at a non-zero PTS. For example, in our setup because we discard probing data and run with "-vsync 2" the first video frame scheduled to the decklink output will have a PTS around 170. Scheduling frames too far into the future will either fail or cause a backlog of frames scheduled far enough into the future that the entire pipeline will stall. Issue can be reproduced with the following command-line: ./ffmpeg -copyts -i foo.ts -f decklink -vcodec v210 -ac 2 'DeckLink Duo (4)' Keep track of the PTS of the first frame received, so that when we enable start playback we can provide that value to the decklink driver. Thanks to Marton Balint for review and suggestion to use AV_NOPTS_VALUE rather than zero for the initial value.

Devin Heitmueller committed 3 years ago

Commit 8fd345f1 parent 6f1c0062 files · +7 −2Browse files

Showing the changes to libavdevice/decklink_enc.cpp (1 of 2 files). Show all

Unified · Split

libavdevice/decklink_enc.cpp+6−2
@@ -486,6 +486,9 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) · 485 unmodified lines
486 ctx->frames_buffer_available_spots--;486 ctx->frames_buffer_available_spots--;
487 pthread_mutex_unlock(&ctx->mutex);487 pthread_mutex_unlock(&ctx->mutex);
488 488
489 if (ctx->first_pts == AV_NOPTS_VALUE)
490 ctx->first_pts = pkt->pts;
491
489 /* Schedule frame for playback. */492 /* Schedule frame for playback. */
490 hr = ctx->dlo->ScheduleVideoFrame((class IDeckLinkVideoFrame *) frame,493 hr = ctx->dlo->ScheduleVideoFrame((class IDeckLinkVideoFrame *) frame,
491 pkt->pts * ctx->bmd_tb_num,494 pkt->pts * ctx->bmd_tb_num,
@@ -505,14 +508,14 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) · 13 unmodified lines
505 " Video may misbehave!\n");508 " Video may misbehave!\n");
506 509
507 /* Preroll video frames. */510 /* Preroll video frames. */
508 if (!ctx->playback_started && pkt->pts > ctx->frames_preroll) {511 if (!ctx->playback_started && pkt->pts > (ctx->first_pts + ctx->frames_preroll)) {
509 av_log(avctx, AV_LOG_DEBUG, "Ending audio preroll.\n");512 av_log(avctx, AV_LOG_DEBUG, "Ending audio preroll.\n");
510 if (ctx->audio && ctx->dlo->EndAudioPreroll() != S_OK) {513 if (ctx->audio && ctx->dlo->EndAudioPreroll() != S_OK) {
511 av_log(avctx, AV_LOG_ERROR, "Could not end audio preroll!\n");514 av_log(avctx, AV_LOG_ERROR, "Could not end audio preroll!\n");
512 return AVERROR(EIO);515 return AVERROR(EIO);
513 }516 }
514 av_log(avctx, AV_LOG_DEBUG, "Starting scheduled playback.\n");517 av_log(avctx, AV_LOG_DEBUG, "Starting scheduled playback.\n");
515 if (ctx->dlo->StartScheduledPlayback(0, ctx->bmd_tb_den, 1.0) != S_OK) {518 if (ctx->dlo->StartScheduledPlayback(ctx->first_pts * ctx->bmd_tb_num, ctx->bmd_tb_den, 1.0) != S_OK) {
516 av_log(avctx, AV_LOG_ERROR, "Could not start scheduled playback!\n");519 av_log(avctx, AV_LOG_ERROR, "Could not start scheduled playback!\n");
517 return AVERROR(EIO);520 return AVERROR(EIO);
518 }521 }
@@ -559,6 +562,7 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) · 40 unmodified lines
559 ctx->list_formats = cctx->list_formats;562 ctx->list_formats = cctx->list_formats;
560 ctx->preroll = cctx->preroll;563 ctx->preroll = cctx->preroll;
561 ctx->duplex_mode = cctx->duplex_mode;564 ctx->duplex_mode = cctx->duplex_mode;
565 ctx->first_pts = AV_NOPTS_VALUE;
562 if (cctx->link > 0 && (unsigned int)cctx->link < FF_ARRAY_ELEMS(decklink_link_conf_map))566 if (cctx->link > 0 && (unsigned int)cctx->link < FF_ARRAY_ELEMS(decklink_link_conf_map))
563 ctx->link = decklink_link_conf_map[cctx->link];567 ctx->link = decklink_link_conf_map[cctx->link];
564 cctx->ctx = ctx;568 cctx->ctx = ctx;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t