Repository navigation
Transcoding pipeline graphs #145
Shadowghost
started this conversation in
Proposals
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
Report what a transcode is actually doing - the ordered chain of decode, filter and encode stages, the hardware framework each one runs on, and the frame format flowing between them - as structured data on
TranscodingInfo, so the dashboard can draw a pipeline graph instead of a codec string. Along the way, fix the telemetry that feeds the existing transcoding display, which is either wrong or missing today.Problem
The active-sessions dashboard is the only place a user can see why their server is on fire, and what it tells them is close to useless:
HardwareAccelerationTypeis a lie by construction. It reports the server configuration, not what the running job does. A direct-stream remux, a software transcode, an audio-only transcode and a subtitle burn-in all report "QSV" on a QSV-configured server. Users read that as "hardware acceleration is working" and file bug reports when it isn't - or, worse, don't file them when it is silently falling back to software.ffmpeglogs on the server.hwupload/hwdownloadround-trips are invisible. A pipeline that decodes in hardware, downloads to system memory for a software filter, and uploads again to encode is a common and very expensive configuration mistake. Nothing surfaces it.Proposal
1. A structured pipeline model on
TranscodingInfoA remux is described as a single
Copystage rather than reported as nothing, so the client never has toguess whether an empty pipeline means "direct play" or "we don't know".
Rendered, a session looks like this:
2. Derive the pipeline from the ffmpeg command line, enriched by
-print_graphsThe command line Jellyfin generates is the most faithful description of the pipeline that is always available: every decoder, filter and encoder is present, and the names encode the framework (
_qsv,_vaapi,_opencl,_rkrga).TranscodingPipelineBuilder.Build()tokenizes it and classifies each element. This path has no runtime cost and works on every supported ffmpeg.ffmpeg 8.0 added
-print_graphs, which dumps the negotiated filter graph as JSON - the real filters after ffmpeg's own insertions, with per-filter output dimensions and pad formats. That is strictly better data, but ffmpeg only flushes it on exit, so the long-running transcode cannot produce it. The proposal runs a short-lived graph probe: the same command line rewritten to-t 0with output redirected to a throwaway directory, which initializes the graph and exits immediately.Probe policy, because a second ffmpeg is not free:
EncoderVersion >= 8.0and the pipeline has a video encode stage (a remux or audio-only transcode has no graph worth dumping)PlaySessionId, so seeks and segment restarts reuse it3. Honest hardware-acceleration reporting
HardwareAccelerationTypebecomes derived from the pipeline: reported only when the job actually has a hardware video stage,noneotherwise. This is a behavioural change - servers configured for hardware acceleration will now correctly shownonefor remuxes, software fallbacks and audio-only transcodes.That is the point, but it will read as a regression to anyone who has learned to read the old field.
4. Fill in the rest of the transcode telemetry
Additive, nullable fields on
TranscodingInfo:Speedspeed=- the single most useful number for "will this keep up?"AudioBitrate,VideoBitrateBitrateBytesTranscodedN/A; cached 5 s, kept monotonic so segment cleanup can't make it go backwardsTranscodePositionTicks,TranscodeBufferTicksIsThrottledSubtitleCodec,SubtitleDeliveryMethodTranscodeProtocolhls/dash/httpPlus the
JobLoggerparsing fixes: decimal bitrate units,KiB/MiB/GiBvskB/MB/GB, padded values,Lsize=on the summary line,N/A, saturating instead of overflowing onGbits/s).API surface
All changes are additive and nullable. No existing field changes type or meaning except
HardwareAccelerationType, whose meaning is corrected as described above.New model types in
MediaBrowser.Model.Session:TranscodingPipelineInfo,TranscodingPipelineStage,TranscodeStageType,HardwareFramework. These flow through the existingSessionInfoDtoon/Sessionsand the sessions WebSocket message - no new endpoints.Clients that ignore
Pipelinecontinue to work unchanged.Client work
jellyfin-webdashboard: render the stage chain as two lanes (video/audio), colour byFramework, badgeIsHardware, showEdgeLabelon connectors, and highlightHardwareUpload/HardwareDownloadtransitions as the "this is costing you" signal.SpeedandIsThrottledbelong next to the existing progress readout.Nothing here is required for the server change to land; the fields are useful in isolation (an admin can already read them via
/Sessions).Risks and open questions
-print_graphsis ffmpeg 8.0+. Everyone below that gets the command-line-derived pipeline, which lacks negotiated formats andEdgeLabel.EncodingHelperevolves. 26 unit tests cover the current filter/codec matrix.BytesTranscodedfor segmented output walks the transcode directory, which is shared by all concurrent jobs. Even if we cache for 5 s; still O(files in directory) per refresh. Fine at typical scale, worth watching on servers with many concurrent HLS sessions.Frontend Mock
All reactions