MCPcopy Create free account
hub / github.com/ClassicOldSong/Apollo / encode_run

Function encode_run

src/video.cpp:1903–2047  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1901 }
1902
1903 void encode_run(
1904 int &frame_nr, // Store progress of the frame number
1905 safe::mail_t mail,
1906 img_event_t images,
1907 config_t config,
1908 std::shared_ptr<platf::display_t> disp,
1909 std::unique_ptr<platf::encode_device_t> encode_device,
1910 safe::signal_t &reinit_event,
1911 const encoder_t &encoder,
1912 void *channel_data
1913 ) {
1914 auto session = make_encode_session(disp.get(), encoder, config, disp->width, disp->height, std::move(encode_device));
1915 if (!session) {
1916 return;
1917 }
1918
1919 // As a workaround for NVENC hangs and to generally speed up encoder reinit,
1920 // we will complete the encoder teardown in a separate thread if supported.
1921 // This will move expensive processing off the encoder thread to allow us
1922 // to restart encoding as soon as possible. For cases where the NVENC driver
1923 // hang occurs, this thread may probably never exit, but it will allow
1924 // streaming to continue without requiring a full restart of Sunshine.
1925 auto fail_guard = util::fail_guard([&encoder, &session] {
1926 if (encoder.flags & ASYNC_TEARDOWN) {
1927 std::thread encoder_teardown_thread {[session = std::move(session)]() mutable {
1928 BOOST_LOG(info) << "Starting async encoder teardown";
1929 session.reset();
1930 BOOST_LOG(info) << "Async encoder teardown complete";
1931 }};
1932 encoder_teardown_thread.detach();
1933 }
1934 });
1935
1936 // set max frame time based on client-requested target framerate.
1937 double minimum_fps_target = (config::video.minimum_fps_target > 0.0) ? config::video.minimum_fps_target * 1000 : std::max(config.encodingFramerate / 5, 10000);
1938 auto max_frametime = std::chrono::nanoseconds(1000ms) * 1000 / minimum_fps_target;
1939 auto encode_frame_threshold = std::chrono::nanoseconds(1000ms) * 1000 / config.encodingFramerate;
1940 auto frame_variation_threshold = encode_frame_threshold / 4;
1941 auto min_frame_diff = encode_frame_threshold - frame_variation_threshold;
1942 BOOST_LOG(info) << "Minimum FPS target set to ~"sv << (minimum_fps_target / 2000) << "fps ("sv << max_frametime * 2 << ")"sv;
1943 BOOST_LOG(info) << "Encoding Frame threshold: "sv << encode_frame_threshold;
1944
1945 auto shutdown_event = mail->event<bool>(mail::shutdown);
1946 auto packets = mail::man->queue<packet_t>(mail::video_packets);
1947 auto idr_events = mail->event<bool>(mail::idr);
1948 auto invalidate_ref_frames_events = mail->event<std::pair<int64_t, int64_t>>(mail::invalidate_ref_frames);
1949
1950 {
1951 // Load a dummy image into the AVFrame to ensure we have something to encode
1952 // even if we timeout waiting on the first frame. This is a relatively large
1953 // allocation which can be freed immediately after convert(), so we do this
1954 // in a separate scope.
1955 auto dummy_img = disp->alloc_img();
1956 if (!dummy_img || disp->dummy_img(dummy_img.get()) || session->convert(*dummy_img)) {
1957 return;
1958 }
1959 }
1960

Callers 1

capture_asyncFunction · 0.85

Calls 15

make_encode_sessionFunction · 0.85
moveFunction · 0.85
fail_guardFunction · 0.85
maxFunction · 0.85
encodeFunction · 0.70
getMethod · 0.45
resetMethod · 0.45
alloc_imgMethod · 0.45
dummy_imgMethod · 0.45
convertMethod · 0.45
peekMethod · 0.45
runningMethod · 0.45

Tested by

no test coverage detected