X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=decklink_output.cpp;h=a826dfe22ee95c5588f86edebec1c2ad1ce64ed3;hb=134f9d70a4cd03dc1105d9d94b6003fedcef4760;hp=46d9b140cb9214e5940e78c5a4656770769a8c00;hpb=138c12c13443d39f8b1168b5d54b36d9835c6405;p=nageru diff --git a/decklink_output.cpp b/decklink_output.cpp index 46d9b14..a826dfe 100644 --- a/decklink_output.cpp +++ b/decklink_output.cpp @@ -1,6 +1,7 @@ #include #include #include // Must be above the Xlib includes. +#include #include @@ -52,13 +53,21 @@ void DeckLinkOutput::set_device(IDeckLink *decklink) } mode_it->Release(); + + // HDMI or SDI generally mean “both HDMI and SDI at the same time” on DeckLink cards + // that support both; pick_default_video_connection() will generally pick one of those + // if they exist. We're not very likely to need analog outputs, so we don't need a way + // to change beyond that. + video_connection = pick_default_video_connection(decklink, BMDDeckLinkVideoOutputConnections, card_index); } void DeckLinkOutput::start_output(uint32_t mode, int64_t base_pts) { assert(output); + assert(!playback_initiated); should_quit = false; + playback_initiated = true; playback_started = false; this->base_pts = base_pts; @@ -71,9 +80,7 @@ void DeckLinkOutput::start_output(uint32_t mode, int64_t base_pts) fprintf(stderr, "Failed to set low latency output\n"); exit(1); } - // HDMI or SDI generally mean “both HDMI and SDI at the same time” on DeckLink cards. - // We're not very likely to need analog outputs. - if (config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionHDMI) != S_OK) { + if (config->SetInt(bmdDeckLinkConfigVideoOutputConnection, video_connection) != S_OK) { fprintf(stderr, "Failed to set video output connection for card %u\n", card_index); exit(1); } @@ -149,9 +156,14 @@ void DeckLinkOutput::start_output(uint32_t mode, int64_t base_pts) void DeckLinkOutput::end_output() { + if (!playback_initiated) { + return; + } + should_quit = true; frame_queues_changed.notify_all(); present_thread.join(); + playback_initiated = false; output->StopScheduledPlayback(0, nullptr, 0); output->DisableVideoOutput(); @@ -169,6 +181,8 @@ void DeckLinkOutput::end_output() void DeckLinkOutput::send_frame(GLuint y_tex, GLuint cbcr_tex, const vector &input_frames, int64_t pts, int64_t duration) { + assert(!should_quit); + unique_ptr frame = move(get_frame()); chroma_subsampler->create_uyvy(y_tex, cbcr_tex, width, height, frame->uyvy_tex); @@ -228,8 +242,10 @@ void DeckLinkOutput::send_audio(int64_t pts, const std::vector &samples) } } -void DeckLinkOutput::wait_for_frame(int64_t pts, int *dropped_frames, int64_t *frame_duration) +void DeckLinkOutput::wait_for_frame(int64_t pts, int *dropped_frames, int64_t *frame_duration, bool *is_preroll) { + assert(!should_quit); + *dropped_frames = 0; *frame_duration = this->frame_duration; @@ -239,9 +255,12 @@ void DeckLinkOutput::wait_for_frame(int64_t pts, int *dropped_frames, int64_t *f // While prerolling, we send out frames as quickly as we can. if (target_time < base_pts) { + *is_preroll = true; return; } + *is_preroll = !playback_started; + if (!playback_started) { if (output->EndAudioPreroll() != S_OK) { fprintf(stderr, "Could not end audio preroll\n"); @@ -350,6 +369,7 @@ unique_ptr DeckLinkOutput::get_frame() void DeckLinkOutput::present_thread_func() { + pthread_setname_np(pthread_self(), "DeckLinkOutput"); for ( ;; ) { unique_ptr frame; {